aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-01-11 16:50:23 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-01-11 16:50:23 +0000
commit2aef1bcb59b97f647bf63b5025c069200f42ec97 (patch)
tree369636a4a765a571e1c6a6ecf2a52ca0131cc90e /libbb
parenta4c67f25b5e304a1b0666bdf1ae3d4c96cecc1e7 (diff)
downloadbusybox-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.c60
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); 86void 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
156static int xsocket_stream_ip4or6(len_and_sockaddr *lsa) 166static 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
223int 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
230static 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
243char* xmalloc_sockaddr2host(const struct sockaddr *sa, socklen_t salen)
244{
245 return sockaddr2str(sa, salen, 0);
246}
247
248char* xmalloc_sockaddr2dotted(const struct sockaddr *sa, socklen_t salen)
249{
250 return sockaddr2str(sa, salen, NI_NUMERICHOST);
251}