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;
{
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;
{
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;
*
* \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 */
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) {
/**
* 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) {
*/
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;
/**
* 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);
/**
*/
/** 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);
*/
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;
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;
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;
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;