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);
/* "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;
}
}
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;
}
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)
int fd;
len_and_sockaddr *lsa;
- if (bindaddr) {
+ if (bindaddr && bindaddr[0]) {
lsa = dotted2sockaddr(bindaddr, port);
/* currently NULL check is in str2sockaddr */
//if (!lsa)
#include <netinet/in.h>
/* 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: */
static void do_syslogd(void)
{
struct sockaddr_un sunx;
- socklen_t addrLength;
+ socklen_t addr_len;
int sock_fd;
fd_set fds;
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);
#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
#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