From a5927501e41fa3fca2975452617474e78ffecc48 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 25 Feb 2010 17:05:45 +0100 Subject: [PATCH] 08_refactor-makesock.diff This is a refactoring of makesock(): * the ubiquitous AF_UNSPEC is promoted as the default; * a wrapper for active sockets, para_connect_simple(); * para_listen() now supports flowopts; * a wrapper for passive sockets, para_listen_simple(); * for consistency, port numbers (which are 2 byte in UDP, TCP, and DCCP) have all been set to 'uint16_t'. --- client_common.c | 4 ++-- dccp_recv.c | 5 ++--- http_recv.c | 4 ++-- net.c | 33 +++++++++++++++------------------ net.h | 18 +++++++++++++++--- send_common.c | 2 +- server.c | 2 +- udp_recv.c | 2 +- udp_send.c | 2 +- 9 files changed, 40 insertions(+), 32 deletions(-) diff --git a/client_common.c b/client_common.c index f3c96aad..197f031c 100644 --- a/client_common.c +++ b/client_common.c @@ -311,8 +311,8 @@ static int client_connect(struct client_task *ct) int ret; ct->rc4c.fd = -1; - ret = makesock(AF_UNSPEC, IPPROTO_TCP, 0, ct->conf.hostname_arg, - ct->conf.server_port_arg, NULL); + ret = para_connect_simple(IPPROTO_TCP, ct->conf.hostname_arg, + ct->conf.server_port_arg); if (ret < 0) return ret; ct->rc4c.fd = ret; diff --git a/dccp_recv.c b/dccp_recv.c index 647d31a6..0a7b3c06 100644 --- a/dccp_recv.c +++ b/dccp_recv.c @@ -57,9 +57,8 @@ static int dccp_recv_open(struct receiver_node *rn) { struct private_dccp_recv_data *pdd; struct dccp_recv_args_info *conf = rn->conf; - int fd, ret = makesock(AF_UNSPEC, IPPROTO_DCCP, 0, conf->host_arg, - conf->port_arg, NULL); - + int fd, ret = para_connect_simple(IPPROTO_DCCP, conf->host_arg, + conf->port_arg); if (ret < 0) return ret; fd = ret; diff --git a/http_recv.c b/http_recv.c index 107bfdcd..3078c5fd 100644 --- a/http_recv.c +++ b/http_recv.c @@ -165,8 +165,8 @@ static int http_recv_open(struct receiver_node *rn) { struct private_http_recv_data *phd; struct http_recv_args_info *conf = rn->conf; - int fd, ret = makesock(AF_UNSPEC, IPPROTO_TCP, 0, conf->host_arg, - conf->port_arg, NULL); + int fd, ret = para_connect_simple(IPPROTO_TCP, conf->host_arg, + conf->port_arg); if (ret < 0) return ret; diff --git a/net.c b/net.c index d85321d9..d9b3a9de 100644 --- a/net.c +++ b/net.c @@ -377,13 +377,14 @@ static void flowopt_cleanup(struct flowopts *fo) * * \sa ipv6(7), getaddrinfo(3), bind(2), connect(2). */ -int makesock(unsigned l3type, unsigned l4type, int passive, - const char *host, unsigned short port_number, +int makesock(unsigned l4type, bool passive, + const char *host, uint16_t port_number, struct flowopts *fo) { struct addrinfo *local = NULL, *src, *remote = NULL, *dst, hints; - int rc, on = 1, sockfd = -1, + unsigned int l3type = AF_UNSPEC; + int rc, sockfd = -1, socktype = sock_type(l4type); char port[6]; /* port number has at most 5 digits */ @@ -428,17 +429,6 @@ int makesock(unsigned l3type, unsigned l4type, int passive, if (sockfd < 0) goto get_next_dst; - /* - * Set those options that need to be set before establishing - * the connection. Reuse the address on passive (listening) - * sockets to avoid failure on restart. - */ - if (passive && setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - &on, sizeof(on)) == -1) { - PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n", - strerror(errno)); - return -ERRNO_TO_PARA_ERROR(errno); - } flowopt_setopts(sockfd, fo); if (src) { @@ -478,19 +468,26 @@ get_next_src: /** * Create a passive / listening socket. * - * \param l3type The network-layer type (\p AF_xxx). * \param l4type The transport-layer type (\p IPPROTO_xxx). * \param port The decimal port number to listen on. + * \param fo Flowopts (if any) to set before starting to listen. * * \return Positive integer (socket descriptor) on success, negative value * otherwise. * * \sa makesock(), ip(7), ipv6(7), bind(2), listen(2). */ -int para_listen(unsigned l3type, unsigned l4type, unsigned short port) +int para_listen(unsigned l4type, uint16_t port, struct flowopts *fo) { - int ret, fd = makesock(l3type, l4type, 1, NULL, port, NULL); + int fd, ret; + + if (fo == NULL) + fo = flowopt_new(); + + /* Reuse the address to avoid failure on restart. */ + OPT_ENABLE(fo, SOL_SOCKET, SO_REUSEADDR); + fd = makesock(l4type, 1, NULL, port, fo); if (fd > 0) { ret = listen(fd, BACKLOG); if (ret < 0) { @@ -782,7 +779,7 @@ int para_accept(int fd, void *addr, socklen_t size) */ const uint8_t *dccp_available_ccids(uint8_t *ccids, uint8_t *nccids) { - int fd = makesock(AF_UNSPEC, IPPROTO_DCCP, 1, NULL, 0, NULL); + int fd = makesock(IPPROTO_DCCP, 1, NULL, 0, NULL); if (fd < 0) return NULL; diff --git a/net.h b/net.h index 96fa07ee..831cd3b8 100644 --- a/net.h +++ b/net.h @@ -87,9 +87,16 @@ _static_inline_ bool is_valid_ipv6_address(const char *address) /** * Generic socket creation (passive and active sockets). */ -extern int makesock(unsigned l3type, unsigned l4type, int passive, - const char *host, unsigned short port_number, +extern int makesock(unsigned l4type, bool passive, + const char *host, uint16_t port_number, struct flowopts *fo); + +static inline int para_connect_simple(unsigned l4type, + const char *host, uint16_t port) +{ + return makesock(l4type, 0, host, port, NULL); +} + extern struct in_addr extract_v4_addr(const struct sockaddr_storage *ss); /** @@ -97,7 +104,12 @@ extern struct in_addr extract_v4_addr(const struct sockaddr_storage *ss); */ /** How many pending connections queue of a listening server will hold. */ #define BACKLOG 10 -extern int para_listen(unsigned l3type, unsigned l4type, unsigned short port); +extern int para_listen(unsigned l4type, uint16_t port, struct flowopts *fo); + +static inline int para_listen_simple(unsigned l4type, uint16_t port) +{ + return para_listen(l4type, port, NULL); +} /** Pretty-printing of IPv4/6 socket addresses */ extern char *local_name(int sockfd); diff --git a/send_common.c b/send_common.c index bc6892cc..d9616248 100644 --- a/send_common.c +++ b/send_common.c @@ -42,7 +42,7 @@ */ static int open_sender(unsigned l4type, int port) { - int fd, ret = para_listen(AF_UNSPEC, l4type, port); + int fd, ret = para_listen_simple(l4type, port); if (ret < 0) return ret; diff --git a/server.c b/server.c index 31123302..71aeaf1c 100644 --- a/server.c +++ b/server.c @@ -425,7 +425,7 @@ static void init_server_command_task(int argc, char **argv) sct->task.post_select = command_post_select; sct->argc = argc; sct->argv = argv; - ret = para_listen(AF_UNSPEC, IPPROTO_TCP, conf.port_arg); + ret = para_listen_simple(IPPROTO_TCP, conf.port_arg); if (ret < 0) goto err; sct->listen_fd = ret; diff --git a/udp_recv.c b/udp_recv.c index 73549453..ae2d49f1 100644 --- a/udp_recv.c +++ b/udp_recv.c @@ -181,7 +181,7 @@ static int udp_recv_open(struct receiver_node *rn) rn->private_data = para_calloc(sizeof(struct private_udp_recv_data)); purd = rn->private_data; - ret = makesock(AF_UNSPEC, IPPROTO_UDP, 1, c->host_arg, c->port_arg, NULL); + ret = makesock(IPPROTO_UDP, 1, c->host_arg, c->port_arg, NULL); if (ret < 0) goto err; purd->fd = ret; diff --git a/udp_send.c b/udp_send.c index 13d2a2ca..4678e936 100644 --- a/udp_send.c +++ b/udp_send.c @@ -160,7 +160,7 @@ static int udp_init_session(struct udp_target *ut) if (ut->fd >= 0) /* nothing to do */ return 0; - ret = makesock(AF_UNSPEC, IPPROTO_UDP, 0, ut->host, ut->port, NULL); + ret = para_connect_simple(IPPROTO_UDP, ut->host, ut->port); if (ret < 0) return ret; ut->fd = ret; -- 2.39.5