From: Ben Pfaff Date: Mon, 23 Nov 2009 20:18:59 +0000 (-0800) Subject: socket-util: Generalize tcp_open_*() to UDP, as inet_open_*(). X-Git-Tag: v0.99.0~19 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=4f2eb9a7e861da23560bb84d50685c836c195419;p=sliver-openvswitch.git socket-util: Generalize tcp_open_*() to UDP, as inet_open_*(). The tcp_open_active() and tcp_open_passive() functions don't really have any strong dependencies on TCP. With a couple of simple changes they can be used for UDP also. Since this is useful for Netflow, this commit does so. --- diff --git a/lib/socket-util.c b/lib/socket-util.c index e400bb543..e6a6c70ef 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -291,10 +291,12 @@ guess_netmask(uint32_t ip) : htonl(0)); /* ??? */ } -/* Opens a non-blocking TCP socket and connects to 'target', which should be a - * string in the format "[:]". is required. If - * 'default_port' is nonzero then is optional and defaults to - * 'default_port'. +/* Opens a non-blocking IPv4 socket of the specified 'style' and connects to + * 'target', which should be a string in the format "[:]". + * is required. If 'default_port' is nonzero then is optional and + * defaults to 'default_port'. + * + * 'style' should be SOCK_STREAM (for TCP) or SOCK_DGRAM (for UDP). * * On success, returns 0 (indicating connection complete) or EAGAIN (indicating * connection in progress), in which case the new file descriptor is stored @@ -304,8 +306,8 @@ guess_netmask(uint32_t ip) * If 'sinp' is non-null, then on success the target address is stored into * '*sinp'. */ int -tcp_open_active(const char *target_, uint16_t default_port, - struct sockaddr_in *sinp, int *fdp) +inet_open_active(int style, const char *target_, uint16_t default_port, + struct sockaddr_in *sinp, int *fdp) { char *target = xstrdup(target_); char *save_ptr = NULL; @@ -343,7 +345,7 @@ tcp_open_active(const char *target_, uint16_t default_port, } /* Create non-blocking socket. */ - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = socket(AF_INET, style, 0); if (fd < 0) { VLOG_ERR("%s: socket: %s", target_, strerror(errno)); error = errno; @@ -380,18 +382,20 @@ exit: return error; } -/* Opens a non-blocking TCP socket, binds to 'target', and listens for incoming - * connections. 'target' should be a string in the format "[][:]". - * may be omitted if 'default_port' is nonzero, in which case it - * defaults to 'default_port'. If is omitted it defaults to the wildcard - * IP address. +/* Opens a non-blocking IPv4 socket of the specified 'style', binds to + * 'target', and listens for incoming connections. 'target' should be a string + * in the format "[][:]". may be omitted if 'default_port' is + * nonzero, in which case it defaults to 'default_port'. If is omitted it + * defaults to the wildcard IP address. + * + * 'style' should be SOCK_STREAM (for TCP) or SOCK_DGRAM (for UDP). * - * The socket will have SO_REUSEADDR turned on. + * For TCP, the socket will have SO_REUSEADDR turned on. * * On success, returns a non-negative file descriptor. On failure, returns a * negative errno value. */ int -tcp_open_passive(const char *target_, uint16_t default_port) +inet_open_passive(int style, const char *target_, uint16_t default_port) { char *target = xstrdup(target_); char *string_ptr = target; @@ -427,7 +431,7 @@ tcp_open_passive(const char *target_, uint16_t default_port) } /* Create non-blocking socket, set SO_REUSEADDR. */ - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = socket(AF_INET, style, 0); if (fd < 0) { error = errno; VLOG_ERR("%s: socket: %s", target_, strerror(error)); @@ -437,7 +441,8 @@ tcp_open_passive(const char *target_, uint16_t default_port) if (error) { goto exit_close; } - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0) { + if (style == SOCK_STREAM + && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) < 0) { error = errno; VLOG_ERR("%s: setsockopt(SO_REUSEADDR): %s", target_, strerror(error)); goto exit_close; diff --git a/lib/socket-util.h b/lib/socket-util.h index febe5e735..4259115d4 100644 --- a/lib/socket-util.h +++ b/lib/socket-util.h @@ -34,9 +34,9 @@ int get_unix_name_len(socklen_t sun_len); uint32_t guess_netmask(uint32_t ip); int get_null_fd(void); -int tcp_open_active(const char *target, uint16_t default_port, +int inet_open_active(int style, const char *target, uint16_t default_port, struct sockaddr_in *sinp, int *fdp); -int tcp_open_passive(const char *target, uint16_t default_port); +int inet_open_passive(int style, const char *target, uint16_t default_port); int read_fully(int fd, void *, size_t, size_t *bytes_read); int write_fully(int fd, const void *, size_t, size_t *bytes_written); diff --git a/lib/vconn-ssl.c b/lib/vconn-ssl.c index 2452bcea5..58c54f877 100644 --- a/lib/vconn-ssl.c +++ b/lib/vconn-ssl.c @@ -288,7 +288,7 @@ ssl_open(const char *name, char *suffix, struct vconn **vconnp) return error; } - error = tcp_open_active(suffix, OFP_SSL_PORT, &sin, &fd); + error = inet_open_active(SOCK_STREAM, suffix, OFP_SSL_PORT, &sin, &fd); if (fd >= 0) { int state = error ? STATE_TCP_CONNECTING : STATE_SSL_CONNECTING; return new_ssl_vconn(name, fd, CLIENT, state, &sin, vconnp); @@ -776,7 +776,7 @@ pssl_open(const char *name, char *suffix, struct pvconn **pvconnp) return retval; } - fd = tcp_open_passive(suffix, OFP_SSL_PORT); + fd = inet_open_passive(SOCK_STREAM, suffix, OFP_SSL_PORT); if (fd < 0) { return -fd; } diff --git a/lib/vconn-tcp.c b/lib/vconn-tcp.c index b4e523435..aac716623 100644 --- a/lib/vconn-tcp.c +++ b/lib/vconn-tcp.c @@ -75,7 +75,7 @@ tcp_open(const char *name, char *suffix, struct vconn **vconnp) struct sockaddr_in sin; int fd, error; - error = tcp_open_active(suffix, OFP_TCP_PORT, &sin, &fd); + error = inet_open_active(SOCK_STREAM, suffix, OFP_TCP_PORT, &sin, &fd); if (fd >= 0) { return new_tcp_vconn(name, fd, error, &sin, vconnp); } else { @@ -104,7 +104,7 @@ ptcp_open(const char *name UNUSED, char *suffix, struct pvconn **pvconnp) { int fd; - fd = tcp_open_passive(suffix, OFP_TCP_PORT); + fd = inet_open_passive(SOCK_STREAM, suffix, OFP_TCP_PORT); if (fd < 0) { return -fd; } else {