diff --git a/src/network/socket.c b/src/network/socket.c index 7c1598541..27388476d 100644 --- a/src/network/socket.c +++ b/src/network/socket.c @@ -534,9 +534,45 @@ connected(struct socket *socket) complete_connect_socket(socket, NULL, NULL); } +static int to_bind; +static int to_bind_ipv6; + +static struct sockaddr_in sa_bind; +static struct sockaddr_in6 sa6_bind; + +static void +init_bind_address(void) +{ + char *bind_address = get_cmd_opt_str("bind-address"); + char *bind_address_ipv6 = get_cmd_opt_str("bind-address-ipv6"); + +#ifdef HAVE_INET_PTON + to_bind = (bind_address && *bind_address); + + if (to_bind) { + memset(&sa_bind, 0, sizeof sa_bind); + sa_bind.sin_family = AF_INET; + inet_pton(AF_INET, bind_address, &(sa_bind.sin_addr)); + sa_bind.sin_port = htons(0); + } + +#ifdef CONFIG_IPV6 + to_bind_ipv6 = (bind_address_ipv6 && *bind_address_ipv6); + + if (to_bind_ipv6) { + memset(&sa6_bind, 0, sizeof sa6_bind); + sa6_bind.sin6_family = AF_INET6; + inet_pton(AF_INET6, bind_address_ipv6, &(sa6_bind.sin6_addr)); + sa6_bind.sin6_port = htons(0); + } +#endif +#endif +} + void connect_socket(struct socket *csocket, struct connection_state state) { + static int initialized; int sock = -1; struct connect_info *connect_info = csocket->connect_info; int i; @@ -554,10 +590,11 @@ connect_socket(struct socket *csocket, struct connection_state state) * about such a connection attempt. * XXX: Unify with @local_only handling? --pasky */ int silent_fail = 0; - char *bind_address = get_cmd_opt_str("bind-address"); - char *bind_address_ipv6 = get_cmd_opt_str("bind-address-ipv6"); - int to_bind = (bind_address && *bind_address); - int to_bind_ipv6 = (bind_address_ipv6 && *bind_address_ipv6); + + if (!initialized) { + init_bind_address(); + initialized = 1; + } csocket->ops->set_state(csocket, state); @@ -634,10 +671,7 @@ connect_socket(struct socket *csocket, struct connection_state state) struct sockaddr_in sa; int res; - memset(&sa, 0, sizeof sa); - sa.sin_family = AF_INET; - inet_pton(AF_INET, bind_address, &(sa.sin_addr)); - sa.sin_port = htons(0); + memcpy(&sa, &sa_bind, sizeof sa); res = bind(sock, (struct sockaddr *)(void *)&sa, sizeof sa); if (res < 0) { @@ -651,10 +685,7 @@ connect_socket(struct socket *csocket, struct connection_state state) struct sockaddr_in6 sa; int res; - memset(&sa, 0, sizeof sa); - sa.sin6_family = AF_INET6; - inet_pton(AF_INET6, bind_address_ipv6, &(sa.sin6_addr)); - sa.sin6_port = htons(0); + memcpy(&sa, &sa6_bind, sizeof sa); res = bind(sock, (struct sockaddr *)(void *)&sa, sizeof sa); if (res < 0) { @@ -665,8 +696,6 @@ connect_socket(struct socket *csocket, struct connection_state state) } #endif #endif - - csocket->fd = sock; #ifdef CONFIG_IPV6