Merge pull request #2147 from wh201906/net

Clean up the code for timeout
This commit is contained in:
Iceman 2023-10-25 19:37:10 +02:00 committed by GitHub
commit 0c0967bcc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 99 additions and 29 deletions

View file

@ -666,9 +666,9 @@ int TestProxmark(pm3_device_t *dev) {
g_conn.send_via_fpc_usart = g_pm3_capabilities.via_fpc;
g_conn.uart_speed = g_pm3_capabilities.baudrate;
bool is_tcp_conn = (memcmp(g_conn.serial_port_name, "tcp:", 4) == 0);
bool is_tcp_conn = (g_conn.send_via_ip == PM3_TCPv4 || g_conn.send_via_ip == PM3_TCPv6);
bool is_bt_conn = (memcmp(g_conn.serial_port_name, "bt:", 3) == 0);
bool is_udp_conn = (memcmp(g_conn.serial_port_name, "udp:", 4) == 0);
bool is_udp_conn = (g_conn.send_via_ip == PM3_UDPv4 || g_conn.send_via_ip == PM3_UDPv6);
PrintAndLogEx(INFO, "Communicating with PM3 over %s%s%s%s",
(g_conn.send_via_fpc_usart) ? _YELLOW_("FPC UART") : _YELLOW_("USB-CDC"),
@ -680,15 +680,11 @@ int TestProxmark(pm3_device_t *dev) {
PrintAndLogEx(INFO, "PM3 UART serial baudrate: " _YELLOW_("%u") "\n", g_conn.uart_speed);
} else {
int res;
if (is_tcp_conn || is_udp_conn) {
if ((strstr(g_conn.serial_port_name, "localhost") != NULL) ||
(strstr(g_conn.serial_port_name, "127.0.0.1") != NULL) ||
(strstr(g_conn.serial_port_name, "[::1]") != NULL) ||
(strstr(g_conn.serial_port_name, "p:::1") != NULL)) {
res = uart_reconfigure_timeouts(UART_TCP_CLIENT_LOCAL_RX_TIMEOUT_MS);
} else {
res = uart_reconfigure_timeouts(UART_TCP_CLIENT_RX_TIMEOUT_MS);
}
if (g_conn.send_via_local_ip) {
// (g_conn.send_via_local_ip == true) -> ((is_tcp_conn || is_udp_conn) == true)
res = uart_reconfigure_timeouts(is_tcp_conn ? UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS : UART_UDP_LOCAL_CLIENT_RX_TIMEOUT_MS);
} else if (is_tcp_conn || is_udp_conn) {
res = uart_reconfigure_timeouts(UART_NET_CLIENT_RX_TIMEOUT_MS);
} else {
res = uart_reconfigure_timeouts(UART_USB_CLIENT_RX_TIMEOUT_MS);
}

View file

@ -70,8 +70,10 @@ typedef struct {
bool send_with_crc_on_fpc;
// "Session" flag, to tell via which interface next msgs are sent: USB or FPC USART
bool send_via_fpc_usart;
// to tell if we are using TCP/UDP/TCPv6
// to tell if we are using TCP/UDP/TCP(IPv6)/UDP(IPv6)
CommunicationProtocol_t send_via_ip;
// to tell if the target address is local address(127.0.0.1/localhost/::1)
bool send_via_local_ip;
// To memorise baudrate
uint32_t uart_speed;
uint16_t last_command;

View file

@ -91,6 +91,8 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
sp->udpBuffer = NULL;
// init timeouts
timeout.tv_usec = UART_FPC_CLIENT_RX_TIMEOUT_MS * 1000;
g_conn.send_via_local_ip = false;
g_conn.send_via_ip = PM3_NONE;
char *prefix = strdup(pcPortName);
if (prefix == NULL) {
@ -119,7 +121,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
return INVALID_SERIAL_PORT;
}
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
timeout.tv_usec = UART_NET_CLIENT_RX_TIMEOUT_MS * 1000;
// find the "bind" option
char *bindAddrPortStr = strstr(addrPortStr, ",bind=");
@ -233,6 +235,12 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
info.ai_family = PF_UNSPEC;
info.ai_socktype = SOCK_STREAM;
if ((strstr(addrstr, "localhost") != NULL) ||
(strstr(addrstr, "127.0.0.1") != NULL) ||
(strstr(addrstr, "::1") != NULL)) {
g_conn.send_via_local_ip = true;
}
int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s));
@ -304,7 +312,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
return INVALID_SERIAL_PORT;
}
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
timeout.tv_usec = UART_NET_CLIENT_RX_TIMEOUT_MS * 1000;
// find the "bind" option
char *bindAddrPortStr = strstr(addrPortStr, ",bind=");
@ -417,6 +425,12 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
info.ai_family = PF_UNSPEC;
info.ai_socktype = SOCK_DGRAM;
if ((strstr(addrstr, "localhost") != NULL) ||
(strstr(addrstr, "127.0.0.1") != NULL) ||
(strstr(addrstr, "::1") != NULL)) {
g_conn.send_via_local_ip = true;
}
int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s));
@ -528,7 +542,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
}
// we must use max timeout!
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
timeout.tv_usec = UART_NET_CLIENT_RX_TIMEOUT_MS * 1000;
size_t servernameLen = (strlen(pcPortName) - 7) + 1;
char serverNameBuf[servernameLen];

View file

@ -44,7 +44,7 @@ typedef struct {
// this is for TCP connection
struct timeval timeout = {
.tv_sec = 0, // 0 second
.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000
.tv_usec = UART_NET_CLIENT_RX_TIMEOUT_MS * 1000
};
uint32_t newtimeout_value = 0;
@ -92,6 +92,8 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
}
sp->udpBuffer = NULL;
g_conn.send_via_local_ip = false;
g_conn.send_via_ip = PM3_NONE;
char *prefix = strdup(pcPortName);
if (prefix == NULL) {
@ -121,7 +123,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
return INVALID_SERIAL_PORT;
}
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
timeout.tv_usec = UART_NET_CLIENT_RX_TIMEOUT_MS * 1000;
// find the "bind" option
char *bindAddrPortStr = strstr(addrPortStr, ",bind=");
@ -244,6 +246,12 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
info.ai_socktype = SOCK_STREAM;
info.ai_protocol = IPPROTO_TCP;
if ((strstr(addrstr, "localhost") != NULL) ||
(strstr(addrstr, "127.0.0.1") != NULL) ||
(strstr(addrstr, "::1") != NULL)) {
g_conn.send_via_local_ip = true;
}
int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %d: %s", s, gai_strerror(s));
@ -322,7 +330,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
return INVALID_SERIAL_PORT;
}
timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000;
timeout.tv_usec = UART_NET_CLIENT_RX_TIMEOUT_MS * 1000;
// find the "bind" option
char *bindAddrPortStr = strstr(addrPortStr, ",bind=");
@ -445,6 +453,12 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
info.ai_socktype = SOCK_DGRAM;
info.ai_protocol = IPPROTO_UDP;
if ((strstr(addrstr, "localhost") != NULL) ||
(strstr(addrstr, "127.0.0.1") != NULL) ||
(strstr(addrstr, "::1") != NULL)) {
g_conn.send_via_local_ip = true;
}
int s = getaddrinfo(addrstr, portstr, &info, &addr);
if (s != 0) {
PrintAndLogEx(ERR, "error: getaddrinfo: %d: %s", s, gai_strerror(s));

View file

@ -332,9 +332,11 @@ else we get errors about partial packet reception
FTDI 460800 hw status ⇒ we need 30ms
BT 115200 hf mf fchk --1k -f file.dic ⇒ we need 140ms
# define UART_FPC_CLIENT_RX_TIMEOUT_MS 170
# define UART_USB_CLIENT_RX_TIMEOUT_MS 20
# define UART_TCP_CLIENT_RX_TIMEOUT_MS 300
# define UART_FPC_CLIENT_RX_TIMEOUT_MS 200
# define UART_USB_CLIENT_RX_TIMEOUT_MS 20
# define UART_NET_CLIENT_RX_TIMEOUT_MS 500
# define UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS 40
# define UART_UDP_LOCAL_CLIENT_RX_TIMEOUT_MS 20
This goes to `uart_posix.c` `timeval` struct
and `uart_win32.c` `serial_port_windows` struct
@ -342,7 +344,7 @@ and `uart_win32.c` `serial_port_windows` struct
It starts at UART_FPC_CLIENT_RX_TIMEOUT_MS and once we detect we're working over USB
it's reduced to UART_USB_CLIENT_RX_TIMEOUT_MS.
The timeout is configurable by the `hw timeout` command (since v4.17140).
Add automatically some communication delay in the `WaitForResponseTimeout` & `dl_it` timeouts.
Only when using FPC, timeout = 2* empirically measured delay (FTDI cable).

View file

@ -15,12 +15,13 @@
* [ Flashing the kernel ](#flashing-the-kernel)
* [ Testing ](#testing)
* [ Troubleshooting ](#troubleshooting)
* [ TCP bridge method ](#tcp-bridge-method)
* [ TCP/UDP bridge method ](#tcpudp-bridge-method)
* [ USB connection ](#usb-connection)
* [ USB-UART bridge application ](#usb-uart-bridge-application)
* [ Bluetooth connection ](#bluetooth-connection)
* [ BT-UART bridge application ](#bt-uart-bridge-application)
* [ TCP connection ](#tcp-connection)
* [ UDP connection ](#udp-connection)
* [Troubleshooting](#troubleshooting-1)
* [BTADDON Missing in Firmware of PM3](#btaddon-missing-in-firmware-of-pm3)
* [Compiling and Flashing a Proxmark3 Firmware from non-root Android](#compiling-and-flashing-a-proxmark3-firmware-from-non-root-android)
@ -125,16 +126,20 @@ Everything should work just like if it was your PC!
- `dmesg | grep usb` - useful debug info
- `/proc/config.gz` - contains your kernel's build configuration. Look for `CONFIG_USB_ACM`, which should be enabled
## TCP bridge method
## TCP/UDP bridge method
^[Top](#top)
Termux doesn't come with usb serial neither bluetooth serial drivers.
However, it is fully integrated with phone's network, so we need to talk to the proxmark using serial to tcp sockets (carried out by android apps).
However, it is fully integrated with phone's network, so we need to talk to the proxmark using serial to TCP/UDP sockets (carried out by other android apps).
```
|Client in Termux| <--TCP/UDP--> |Bridge App| <--USB/Bluetooth--> |Proxmark3|
```
### USB connection
^[Top](#top)
#### USB-UART Bridge Application
#### USB-UART Bridge Application for TCP to USB bridging
^[Top](#top)
Install [this free TCPUART app](https://play.google.com/store/apps/details?id=com.hardcodedjoy.tcpuart) on the Play Store
@ -153,7 +158,7 @@ It is possible to record the config as autostart, cf 'Settings' -> 'Autostart se
### Bluetooth connection
^[Top](#top)
#### BT-UART Bridge Application
#### BT-UART Bridge Application for TCP to BT bridging
^[Top](#top)
Install [this free app](https://play.google.com/store/apps/details?id=masar.bb) or [the paid version](https://play.google.com/store/apps/details?id=masar.bluetoothbridge.pro) (which includes usb bridge)
@ -175,6 +180,42 @@ Alternatively, if you have made the client in the git repo:
```
./client/proxmark3 tcp:localhost:<chosenPort>
```
If the last colon and the chosen port are missing, the client will use `18888` as the default port.
### UDP connection
^[Top](#top)
Start a new session, then:
```
proxmark3 udp:localhost:<chosenPort>
```
Alternatively, if you have made the client in the git repo:
```
./client/proxmark3 udp:localhost:<chosenPort>
```
If the last colon and the chosen port are missing, the client will use `18888` as the default port.
You can also specify the outbound port for UDP connections, which might be required for some UDP to USB/BT bridge app as the target port of it.
The format is
```
proxmark3 udp:localhost:<chosenPort>,bind=:<outboundPort>
```
Some examples:
```
# The bridge app listens on Port 12345, and the client listens on Port 12355
proxmark3 udp:localhost:12345,bind=:12355
# 127.0.0.1 is also a valid local address
proxmark3 udp:127.0.0.1:12345,bind=:12355
# The bridge app listens on the default port 18888, and the client listens on Port 12355
proxmark3 udp:127.0.0.1,bind=:12355
# OutboundPort is randomly picked by the system, which requires the "UDP server" mode for the bridge app
proxmark3 udp:localhost:12345
```
### Troubleshooting
^[Top](#top)

View file

@ -831,8 +831,9 @@ typedef struct {
// uart_windows.c & uart_posix.c
# define UART_FPC_CLIENT_RX_TIMEOUT_MS 200
# define UART_USB_CLIENT_RX_TIMEOUT_MS 20
# define UART_TCP_CLIENT_RX_TIMEOUT_MS 500
# define UART_TCP_CLIENT_LOCAL_RX_TIMEOUT_MS 40
# define UART_NET_CLIENT_RX_TIMEOUT_MS 500
# define UART_TCP_LOCAL_CLIENT_RX_TIMEOUT_MS 40
# define UART_UDP_LOCAL_CLIENT_RX_TIMEOUT_MS 20
// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: