diff options
| author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-01-11 16:50:23 +0000 |
|---|---|---|
| committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2007-01-11 16:50:23 +0000 |
| commit | 2aef1bcb59b97f647bf63b5025c069200f42ec97 (patch) | |
| tree | 369636a4a765a571e1c6a6ecf2a52ca0131cc90e /libbb | |
| parent | a4c67f25b5e304a1b0666bdf1ae3d4c96cecc1e7 (diff) | |
| download | busybox-w32-2aef1bcb59b97f647bf63b5025c069200f42ec97.tar.gz busybox-w32-2aef1bcb59b97f647bf63b5025c069200f42ec97.tar.bz2 busybox-w32-2aef1bcb59b97f647bf63b5025c069200f42ec97.zip | |
ipv6-ization efforts continue. Few bugs are found,
unknown number likely introduced...
git-svn-id: svn://busybox.net/trunk/busybox@17250 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/xconnect.c | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 6e85322cf..a5b16d982 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
| @@ -83,8 +83,20 @@ int xconnect_tcp_v4(struct sockaddr_in *s_addr) | |||
| 83 | /* "New" networking API */ | 83 | /* "New" networking API */ |
| 84 | 84 | ||
| 85 | 85 | ||
| 86 | //extern int xsocket_stream_ip4or6(sa_family_t *fp); | 86 | void set_port(len_and_sockaddr *lsa, unsigned port) |
| 87 | //extern len_and_sockaddr* dotted2sockaddr(const char *dotted, int def_port); | 87 | { |
| 88 | #if ENABLE_FEATURE_IPV6 | ||
| 89 | if (lsa->sa.sa_family == AF_INET6) { | ||
| 90 | lsa->sin6.sin6_port = port; | ||
| 91 | return; | ||
| 92 | } | ||
| 93 | #endif | ||
| 94 | if (lsa->sa.sa_family == AF_INET) { | ||
| 95 | lsa->sin.sin_port = port; | ||
| 96 | return; | ||
| 97 | } | ||
| 98 | /* What? UNIX socket? IPX?? :) */ | ||
| 99 | } | ||
| 88 | 100 | ||
| 89 | /* peer: "1.2.3.4[:port]", "www.google.com[:port]" | 101 | /* peer: "1.2.3.4[:port]", "www.google.com[:port]" |
| 90 | * port: if neither of above specifies port # | 102 | * port: if neither of above specifies port # |
| @@ -96,7 +108,6 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) | |||
| 96 | struct addrinfo *result = NULL; | 108 | struct addrinfo *result = NULL; |
| 97 | const char *org_host = host; /* only for error msg */ | 109 | const char *org_host = host; /* only for error msg */ |
| 98 | const char *cp; | 110 | const char *cp; |
| 99 | char service[sizeof(int)*3 + 1]; | ||
| 100 | struct addrinfo hint; | 111 | struct addrinfo hint; |
| 101 | 112 | ||
| 102 | /* Ugly parsing of host:addr */ | 113 | /* Ugly parsing of host:addr */ |
| @@ -119,9 +130,7 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) | |||
| 119 | if (ENABLE_FEATURE_IPV6 && *cp != ':') | 130 | if (ENABLE_FEATURE_IPV6 && *cp != ':') |
| 120 | cp++; /* skip ']' */ | 131 | cp++; /* skip ']' */ |
| 121 | cp++; /* skip ':' */ | 132 | cp++; /* skip ':' */ |
| 122 | } else { | 133 | port = xatou16(cp); |
| 123 | utoa_to_buf(port, service, sizeof(service)); | ||
| 124 | cp = service; | ||
| 125 | } | 134 | } |
| 126 | 135 | ||
| 127 | memset(&hint, 0 , sizeof(hint)); | 136 | memset(&hint, 0 , sizeof(hint)); |
| @@ -132,13 +141,14 @@ static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) | |||
| 132 | /* Needed. Or else we will get each address thrice (or more) | 141 | /* Needed. Or else we will get each address thrice (or more) |
| 133 | * for each possible socket type (tcp,udp,raw...): */ | 142 | * for each possible socket type (tcp,udp,raw...): */ |
| 134 | hint.ai_socktype = SOCK_STREAM; | 143 | hint.ai_socktype = SOCK_STREAM; |
| 135 | hint.ai_flags = ai_flags | AI_NUMERICSERV; | 144 | hint.ai_flags = ai_flags; |
| 136 | rc = getaddrinfo(host, cp, &hint, &result); | 145 | rc = getaddrinfo(host, NULL, &hint, &result); |
| 137 | if (rc || !result) | 146 | if (rc || !result) |
| 138 | bb_error_msg_and_die("bad address '%s'", org_host); | 147 | bb_error_msg_and_die("bad address '%s'", org_host); |
| 139 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); | 148 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); |
| 140 | r->len = result->ai_addrlen; | 149 | r->len = result->ai_addrlen; |
| 141 | memcpy(&r->sa, result->ai_addr, result->ai_addrlen); | 150 | memcpy(&r->sa, result->ai_addr, result->ai_addrlen); |
| 151 | set_port(r, port); | ||
| 142 | freeaddrinfo(result); | 152 | freeaddrinfo(result); |
| 143 | return r; | 153 | return r; |
| 144 | } | 154 | } |
| @@ -153,7 +163,7 @@ static len_and_sockaddr* dotted2sockaddr(const char *host, int port) | |||
| 153 | return str2sockaddr(host, port, NI_NUMERICHOST); | 163 | return str2sockaddr(host, port, NI_NUMERICHOST); |
| 154 | } | 164 | } |
| 155 | 165 | ||
| 156 | static int xsocket_stream_ip4or6(len_and_sockaddr *lsa) | 166 | static int xsocket_stream(len_and_sockaddr *lsa) |
| 157 | { | 167 | { |
| 158 | int fd; | 168 | int fd; |
| 159 | #if ENABLE_FEATURE_IPV6 | 169 | #if ENABLE_FEATURE_IPV6 |
| @@ -186,7 +196,7 @@ int create_and_bind_stream_or_die(const char *bindaddr, int port) | |||
| 186 | USE_FEATURE_IPV6(sizeof(struct sockaddr_in6)) | 196 | USE_FEATURE_IPV6(sizeof(struct sockaddr_in6)) |
| 187 | SKIP_FEATURE_IPV6(sizeof(struct sockaddr_in)) | 197 | SKIP_FEATURE_IPV6(sizeof(struct sockaddr_in)) |
| 188 | ); | 198 | ); |
| 189 | fd = xsocket_stream_ip4or6(lsa); | 199 | fd = xsocket_stream(lsa); |
| 190 | } | 200 | } |
| 191 | setsockopt_reuseaddr(fd); | 201 | setsockopt_reuseaddr(fd); |
| 192 | xbind(fd, &lsa->sa, lsa->len); | 202 | xbind(fd, &lsa->sa, lsa->len); |
| @@ -209,3 +219,33 @@ int create_and_connect_stream_or_die(const char *peer, int port) | |||
| 209 | free(lsa); | 219 | free(lsa); |
| 210 | return fd; | 220 | return fd; |
| 211 | } | 221 | } |
| 222 | |||
| 223 | int xconnect_stream(const len_and_sockaddr *lsa) | ||
| 224 | { | ||
| 225 | int fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); | ||
| 226 | xconnect(fd, &lsa->sa, lsa->len); | ||
| 227 | return fd; | ||
| 228 | } | ||
| 229 | |||
| 230 | static char* sockaddr2str(const struct sockaddr *sa, socklen_t salen, int flags) | ||
| 231 | { | ||
| 232 | char host[128]; | ||
| 233 | char serv[16]; | ||
| 234 | int rc = getnameinfo(sa, salen, | ||
| 235 | host, sizeof(host), | ||
| 236 | serv, sizeof(serv), | ||
| 237 | flags | NI_NUMERICSERV /* do not resolve port# */ | ||
| 238 | ); | ||
| 239 | if (rc) return NULL; | ||
| 240 | return xasprintf("%s:%s", host, serv); | ||
| 241 | } | ||
| 242 | |||
| 243 | char* xmalloc_sockaddr2host(const struct sockaddr *sa, socklen_t salen) | ||
| 244 | { | ||
| 245 | return sockaddr2str(sa, salen, 0); | ||
| 246 | } | ||
| 247 | |||
| 248 | char* xmalloc_sockaddr2dotted(const struct sockaddr *sa, socklen_t salen) | ||
| 249 | { | ||
| 250 | return sockaddr2str(sa, salen, NI_NUMERICHOST); | ||
| 251 | } | ||
