diff --git a/src/local.c b/src/local.c index 5c4aac79..c3859338 100644 --- a/src/local.c +++ b/src/local.c @@ -435,7 +435,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) } struct sockaddr_storage storage; memset(&storage, 0, sizeof(struct sockaddr_storage)); - if (get_sockaddr(host, port, &storage) != -1) { + if (get_sockaddr(host, port, &storage, 0) != -1) { remote = connect_to_remote(server->listener, (struct sockaddr *)&storage); remote->direct = 1; } @@ -1075,7 +1075,7 @@ int main(int argc, char **argv) remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); - if (get_sockaddr(host, port, storage) == -1) { + if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; @@ -1205,7 +1205,7 @@ int start_ss_local_server(profile_t profile) listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *)); struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); - if (get_sockaddr(remote_host, remote_port_str, storage) == -1) { + if (get_sockaddr(remote_host, remote_port_str, storage, 1) == -1) { return -1; } listen_ctx.remote_addr[0] = (struct sockaddr *)storage; diff --git a/src/netutils.c b/src/netutils.c index d787dce4..1f2865ec 100644 --- a/src/netutils.c +++ b/src/netutils.c @@ -20,6 +20,9 @@ * . */ +#include +#include + #include #include @@ -48,7 +51,7 @@ int get_sockaddr_len(struct sockaddr *addr) return 0; } -int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage) +int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage, int block) { struct cork_ip ip; if (cork_ip_init(&ip, host) != -1) { @@ -76,7 +79,18 @@ int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage) hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ - int err = getaddrinfo(host, port, &hints, &result); + int err; + + for (int i = 1; i < 8; i++) { + err = getaddrinfo(host, port, &hints, &result); + if (!block || !err) { + break; + } else { + sleep(pow(2, i)); + LOGE("failed to resolve server name, wait %.0f seconds", pow(2, i)); + } + } + if (err != 0) { LOGE("getaddrinfo: %s", gai_strerror(err)); return -1; diff --git a/src/netutils.h b/src/netutils.h index cc8bfa2c..5179a241 100644 --- a/src/netutils.h +++ b/src/netutils.h @@ -21,4 +21,4 @@ */ int get_sockaddr_len(struct sockaddr *addr); -int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage); +int get_sockaddr(char *host, char *port, struct sockaddr_storage *storage, int block); diff --git a/src/redir.c b/src/redir.c index 931554b8..fd32b9ed 100644 --- a/src/redir.c +++ b/src/redir.c @@ -731,7 +731,7 @@ int main(int argc, char **argv) remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); - if (get_sockaddr(host, port, storage) == -1) { + if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; diff --git a/src/server.c b/src/server.c index f2b755f3..354cb402 100644 --- a/src/server.c +++ b/src/server.c @@ -124,13 +124,14 @@ static void free_connections(struct ev_loop *loop) } } -static void report_addr(int fd) { +static void report_addr(int fd) +{ struct sockaddr_storage addr; socklen_t len = sizeof addr; memset(&addr, 0, len); int err = getpeername(fd, (struct sockaddr *)&addr, &len); if (err == 0) { - char peer_name[INET6_ADDRSTRLEN] = {0}; + char peer_name[INET6_ADDRSTRLEN] = { 0 }; if (addr.ss_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)&addr; dns_ntop(AF_INET, &s->sin_addr, peer_name, INET_ADDRSTRLEN); @@ -172,19 +173,19 @@ int create_and_bind(const char *host, const char *port) int s, listen_sock; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ - hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ + hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ + hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ hints.ai_protocol = IPPROTO_TCP; for (int i = 1; i < 8; i++) { s = getaddrinfo(host, port, &hints, &result); - if (s == 0) break; - else { + if (s == 0) { + break; + } else { sleep(pow(2, i)); LOGE("failed to resolve server name, wait %.0f seconds", pow(2, i)); } - } if (s != 0) { @@ -677,7 +678,7 @@ static void server_resolve_cb(struct sockaddr *addr, void *data) } if (acl) { - char host[INET6_ADDRSTRLEN] = {0}; + char host[INET6_ADDRSTRLEN] = { 0 }; if (addr->sa_family == AF_INET) { struct sockaddr_in *s = (struct sockaddr_in *)addr; dns_ntop(AF_INET, &s->sin_addr, host, INET_ADDRSTRLEN); @@ -1085,9 +1086,9 @@ int main(int argc, char **argv) int option_index = 0; static struct option long_options[] = { - { "fast-open", no_argument, 0, 0 }, + { "fast-open", no_argument, 0, 0 }, { "acl", required_argument, 0, 0 }, - { 0, 0, 0, 0 } + { 0, 0, 0, 0 } }; opterr = 0; @@ -1297,7 +1298,7 @@ int main(int argc, char **argv) // Setup UDP if (udprelay) { init_udprelay(server_host[index], server_port, m, atoi(timeout), - iface); + iface); } } diff --git a/src/tunnel.c b/src/tunnel.c index 2959f940..536bd449 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -797,7 +797,7 @@ int main(int argc, char **argv) remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); - if (get_sockaddr(host, port, storage) == -1) { + if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; diff --git a/src/udprelay.c b/src/udprelay.c index 3ba3a2b2..3b2fab17 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -317,8 +317,8 @@ int create_server_socket(const char *host, const char *port) int s, server_sock; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ - hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */ + hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ + hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; /* For wildcard IP address */ hints.ai_protocol = IPPROTO_UDP;