diff --git a/app/src/server.c b/app/src/server.c index 473bbeed..abf9170e 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -116,10 +116,10 @@ disable_tunnel(struct server *server) { return ok; } -static sc_socket -listen_on_port(uint16_t port) { +static bool +listen_on_port(sc_socket socket, uint16_t port) { #define IPV4_LOCALHOST 0x7F000001 - return net_listen(IPV4_LOCALHOST, port, 1); + return net_listen(socket, IPV4_LOCALHOST, port, 1); } static bool @@ -138,13 +138,18 @@ enable_tunnel_reverse_any_port(struct server *server, // client can listen before starting the server app, so there is no // need to try to connect until the server socket is listening on the // device. - sc_socket server_socket = listen_on_port(port); + sc_socket server_socket = net_socket(); if (server_socket != SC_INVALID_SOCKET) { - // success - server->server_socket = server_socket; - server->local_port = port; - server->tunnel_enabled = true; - return true; + bool ok = listen_on_port(server_socket, port); + if (ok) { + // success + server->server_socket = server_socket; + server->local_port = port; + server->tunnel_enabled = true; + return true; + } + + net_close(server_socket); } // failure, disable tunnel and try another port @@ -299,11 +304,11 @@ execute_server(struct server *server, const struct server_params *params) { return adb_execute(server->serial, cmd, ARRAY_LEN(cmd)); } -static sc_socket -connect_and_read_byte(uint16_t port) { - sc_socket socket = net_connect(IPV4_LOCALHOST, port); - if (socket == SC_INVALID_SOCKET) { - return SC_INVALID_SOCKET; +static bool +connect_and_read_byte(sc_socket socket, uint16_t port) { + bool ok = net_connect(socket, IPV4_LOCALHOST, port); + if (!ok) { + return false; } char byte; @@ -311,20 +316,25 @@ connect_and_read_byte(uint16_t port) { // is not listening, so read one byte to detect a working connection if (net_recv(socket, &byte, 1) != 1) { // the server is not listening yet behind the adb tunnel - net_close(socket); - return SC_INVALID_SOCKET; + return false; } - return socket; + + return true; } static sc_socket connect_to_server(uint16_t port, uint32_t attempts, uint32_t delay) { do { LOGD("Remaining connection attempts: %d", (int) attempts); - sc_socket socket = connect_and_read_byte(port); + sc_socket socket = net_socket(); if (socket != SC_INVALID_SOCKET) { - // it worked! - return socket; + bool ok = connect_and_read_byte(socket, port); + if (ok) { + // it worked! + return socket; + } + + net_close(socket); } if (attempts) { SDL_Delay(delay); @@ -463,10 +473,15 @@ server_connect_to(struct server *server, struct server_info *info) { } // we know that the device is listening, we don't need several attempts - control_socket = net_connect(IPV4_LOCALHOST, server->local_port); + control_socket = net_socket(); if (control_socket == SC_INVALID_SOCKET) { goto fail; } + bool ok = net_connect(control_socket, IPV4_LOCALHOST, + server->local_port); + if (!ok) { + goto fail; + } } // we don't need the adb tunnel anymore diff --git a/app/src/util/net.c b/app/src/util/net.c index cfc60433..6bfe7a52 100644 --- a/app/src/util/net.c +++ b/app/src/util/net.c @@ -94,13 +94,18 @@ net_perror(const char *s) { } sc_socket -net_connect(uint32_t addr, uint16_t port) { +net_socket(void) { sc_raw_socket raw_sock = socket(AF_INET, SOCK_STREAM, 0); sc_socket sock = wrap(raw_sock); if (sock == SC_INVALID_SOCKET) { net_perror("socket"); - return SC_INVALID_SOCKET; } + return sock; +} + +bool +net_connect(sc_socket socket, uint32_t addr, uint16_t port) { + sc_raw_socket raw_sock = unwrap(socket); SOCKADDR_IN sin; sin.sin_family = AF_INET; @@ -109,21 +114,15 @@ net_connect(uint32_t addr, uint16_t port) { if (connect(raw_sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) { net_perror("connect"); - net_close(sock); - return SC_INVALID_SOCKET; + return false; } - return sock; + return true; } -sc_socket -net_listen(uint32_t addr, uint16_t port, int backlog) { - sc_raw_socket raw_sock = socket(AF_INET, SOCK_STREAM, 0); - sc_socket sock = wrap(raw_sock); - if (sock == SC_INVALID_SOCKET) { - net_perror("socket"); - return SC_INVALID_SOCKET; - } +bool +net_listen(sc_socket socket, uint32_t addr, uint16_t port, int backlog) { + sc_raw_socket raw_sock = unwrap(socket); int reuse = 1; if (setsockopt(raw_sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, @@ -138,17 +137,15 @@ net_listen(uint32_t addr, uint16_t port, int backlog) { if (bind(raw_sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) { net_perror("bind"); - net_close(sock); - return SC_INVALID_SOCKET; + return false; } if (listen(raw_sock, backlog) == SOCKET_ERROR) { net_perror("listen"); - net_close(sock); - return SC_INVALID_SOCKET; + return false; } - return sock; + return true; } sc_socket diff --git a/app/src/util/net.h b/app/src/util/net.h index c742c00e..9d675a2d 100644 --- a/app/src/util/net.h +++ b/app/src/util/net.h @@ -31,10 +31,13 @@ void net_cleanup(void); sc_socket -net_connect(uint32_t addr, uint16_t port); +net_socket(void); -sc_socket -net_listen(uint32_t addr, uint16_t port, int backlog); +bool +net_connect(sc_socket socket, uint32_t addr, uint16_t port); + +bool +net_listen(sc_socket socket, uint32_t addr, uint16_t port, int backlog); sc_socket net_accept(sc_socket server_socket);