diff options
| -rw-r--r-- | network.c | 55 | ||||
| -rw-r--r-- | network.h | 1 | 
2 files changed, 56 insertions, 0 deletions
| @@ -18,3 +18,58 @@ const char *addr_to_str(struct sockaddr *sa, socklen_t len) {  	}  	return str;  } + +int create_socket(struct sockaddr *sa, size_t sock_len) { +	const int one = 1; +	/* Create a new listen socket. */ +	const int fd = socket(sa->sa_family, SOCK_SEQPACKET, IPPROTO_SCTP); +	int ret = fd; + +	/* Did we fail to create the listen socket? */ +	if (fd < 0) { +		log_reason(LOG_ERR, "Failed to create listen socket.", strerror(errno)); +		return -1; +	} + +	/* Do we have an IPv6 socket? */ +	if (sa->sa_family == AF_INET6) { +		int set = 1; +		setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &set, sizeof(set)); +	} + +	/* Did we fail to enable SO_REUSEADDR? */ +	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) { +		log_reason(LOG_ERR, "Failed to enable SO_REUSEADDR.", strerror(errno)); +		ret = -1; +	} + + +	/* Did we fail to bind the listen socket? */ +	if (ret >= 0 && bind(fd, sa, sock_len) < 0) { +		log_reason(LOG_ERR, "Failed to bind listen socket.", strerror(errno)); +		ret = -1; +	} + +	/* Did we fail to listen to the socket? */ +	if (ret >= 0 && listen(fd, 20) < 0) { +		log_reason(LOG_ERR, "Failed to listen to socket.", strerror(errno)); +		ret = -1; +	} + +	/* Did we get an error? */ +	if (ret < 0) { +		/* Close the socket. */ +		close(fd); +		/* Is this a unix domain socket? */ +		if (sa->sa_family == AF_UNIX) { +			struct sockaddr_un *sa_un = (struct sockaddr_un *)sa; +			/* Unlink the path. */ +			unlink(sa_un->sun_path); +		} +		log(LOG_ERR, "Failed to create socket for address \"%s\".", addr_to_str(sa, sock_len)); +	} else { +		log(LOG_INFO, "Successfully created socket descriptor %i for address \"%s\".", fd, addr_to_str(sa, sock_len)); +	} + +	return ret; +} @@ -32,5 +32,6 @@ struct packet {  };  extern const char *addr_to_str(struct sockaddr *sa, socklen_t len); +extern int create_socket(struct sockaddr *sa, size_t sock_len);  #endif | 
