diff --git a/include/libbb.h b/include/libbb.h index 16f092f60..62d5fcee4 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -298,12 +298,29 @@ extern int setsockopt_reuseaddr(int fd); extern int setsockopt_broadcast(int fd); /* Create server TCP socket bound to bindaddr:port. bindaddr can be NULL, * numeric IP ("N.N.N.N") or numeric IPv6 address, - * and can have ":PORT" suffix. If no suffix trere, second argument is used */ + * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT"). + * If there is no suffix, port argument is used */ extern int create_and_bind_stream_or_die(const char *bindaddr, int port); /* Create client TCP socket connected to peer:port. Peer cannot be NULL. * Peer can be numeric IP ("N.N.N.N"), numeric IPv6 address or hostname, - * and can have ":PORT" suffix. If no suffix trere, second argument is used */ -extern int create_and_connect_stream_or_die(const char *peer, int def_port); + * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT"). + * If there is no suffix, port argument is used */ +extern int create_and_connect_stream_or_die(const char *peer, int port); +typedef struct len_and_sockaddr { + int len; + union { + struct sockaddr sa; + struct sockaddr_in sin; +#if ENABLE_FEATURE_IPV6 + struct sockaddr_in6 sin6; +#endif + }; +} len_and_sockaddr; +/* Return malloc'ed len_and_sockaddr with socket address of host:port + * Currently will return IPv4 or IPv6 sockaddrs only + * (depending on host), but in theory nothing prevents e.g. + * UNIX socket address being returned, IPX sockaddr etc... */ +extern len_and_sockaddr* host2sockaddr(const char *host, int port); extern char *xstrdup(const char *s); diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 93c3cd5c6..6e85322cf 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -83,25 +83,13 @@ int xconnect_tcp_v4(struct sockaddr_in *s_addr) /* "New" networking API */ -/* So far we do not expose struct and helpers to libbb */ -typedef struct len_and_sockaddr { - int len; - union { - struct sockaddr sa; - struct sockaddr_in sin; -#if ENABLE_FEATURE_IPV6 - struct sockaddr_in6 sin6; -#endif - }; -} len_and_sockaddr; //extern int xsocket_stream_ip4or6(sa_family_t *fp); -//extern len_and_sockaddr* host2sockaddr(const char *host, int def_port); //extern len_and_sockaddr* dotted2sockaddr(const char *dotted, int def_port); /* peer: "1.2.3.4[:port]", "www.google.com[:port]" - * def_port: if neither of above specifies port # + * port: if neither of above specifies port # */ -static len_and_sockaddr* str2sockaddr(const char *host, int def_port, int ai_flags) +static len_and_sockaddr* str2sockaddr(const char *host, int port, int ai_flags) { int rc; len_and_sockaddr *r; // = NULL; @@ -126,12 +114,13 @@ static len_and_sockaddr* str2sockaddr(const char *host, int def_port, int ai_fla } } if (cp) { - host = safe_strncpy(alloca(cp - host + 1), host, cp - host); + int sz = cp - host + 1; + host = safe_strncpy(alloca(sz), host, sz); if (ENABLE_FEATURE_IPV6 && *cp != ':') cp++; /* skip ']' */ cp++; /* skip ':' */ } else { - utoa_to_buf(def_port, service, sizeof(service)); + utoa_to_buf(port, service, sizeof(service)); cp = service; } @@ -154,14 +143,14 @@ static len_and_sockaddr* str2sockaddr(const char *host, int def_port, int ai_fla return r; } -static len_and_sockaddr* host2sockaddr(const char *host, int def_port) +len_and_sockaddr* host2sockaddr(const char *host, int port) { - return str2sockaddr(host, def_port, 0); + return str2sockaddr(host, port, 0); } -static len_and_sockaddr* dotted2sockaddr(const char *host, int def_port) +static len_and_sockaddr* dotted2sockaddr(const char *host, int port) { - return str2sockaddr(host, def_port, NI_NUMERICHOST); + return str2sockaddr(host, port, NI_NUMERICHOST); } static int xsocket_stream_ip4or6(len_and_sockaddr *lsa) @@ -185,7 +174,7 @@ int create_and_bind_stream_or_die(const char *bindaddr, int port) int fd; len_and_sockaddr *lsa; - if (bindaddr) { + if (bindaddr && bindaddr[0]) { lsa = dotted2sockaddr(bindaddr, port); /* currently NULL check is in str2sockaddr */ //if (!lsa) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index aa7d516d6..405282796 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -53,7 +53,7 @@ static smallint isRegular; #include /* udp socket for logging to remote host */ static int remoteFD = -1; -static struct sockaddr_in remoteAddr; +static len_and_sockaddr* remoteAddr; #endif /* We are using bb_common_bufsiz1 for buffering: */ @@ -464,7 +464,7 @@ static void do_syslogd(void) ATTRIBUTE_NORETURN; static void do_syslogd(void) { struct sockaddr_un sunx; - socklen_t addrLength; + socklen_t addr_len; int sock_fd; fd_set fds; @@ -491,8 +491,8 @@ static void do_syslogd(void) sunx.sun_family = AF_UNIX; strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path)); sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0); - addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path); - xbind(sock_fd, (struct sockaddr *) &sunx, addrLength); + addr_len = sizeof(sunx.sun_family) + strlen(sunx.sun_path); + xbind(sock_fd, (struct sockaddr *) &sunx, addr_len); if (chmod(dev_log_name, 0666) < 0) { bb_perror_msg_and_die("cannot set permission on %s", dev_log_name); @@ -524,15 +524,14 @@ static void do_syslogd(void) #if ENABLE_FEATURE_REMOTE_LOG /* We are not modifying log messages in any way before send */ /* Remote site cannot trust _us_ anyway and need to do validation again */ - if (option_mask32 & OPT_remotelog) { + if (remoteAddr) { if (-1 == remoteFD) { - remoteFD = socket(AF_INET, SOCK_DGRAM, 0); + remoteFD = socket(remoteAddr->sa.sa_family, SOCK_DGRAM, 0); } if (-1 != remoteFD) { /* send message to remote logger, ignore possible error */ sendto(remoteFD, RECVBUF, i, MSG_DONTWAIT, - (struct sockaddr *) &remoteAddr, - sizeof(remoteAddr)); + &remoteAddr->sa, remoteAddr->len); } } #endif @@ -565,15 +564,7 @@ int syslogd_main(int argc, char **argv) #endif #if ENABLE_FEATURE_REMOTE_LOG if (option_mask32 & OPT_remotelog) { // -R - int port = 514; - p = strchr(opt_R, ':'); - if (p) { - *p++ = '\0'; - port = xatou16(p); - } - /* FIXME: looks ip4-specific. need to do better */ - bb_lookup_host(&remoteAddr, opt_R); - remoteAddr.sin_port = bb_lookup_port(port, "udp", port); + remoteAddr = host2sockaddr(opt_R, 514); } //if (option_mask32 & OPT_locallog) // -L #endif