Created
November 15, 2024 23:16
-
-
Save v2px/4489f27781f96a642e8a05da9129af31 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <sys/errno.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include "log.h" | |
static const int enable = 1; | |
static const int disable = 0; | |
const char *lookup_af(int af) { | |
switch(af) { | |
case AF_INET: | |
return "AF_INET"; | |
case AF_INET6: | |
return "AF_INET6"; | |
} | |
return "UNDEF"; | |
} | |
int detect_af(const char *address) { | |
int colon = 0; | |
for(int i = 0; address[i]; i++) { | |
if(':' == address[i]) | |
colon++; | |
} | |
switch(colon) { | |
case 0: | |
return AF_INET; | |
case 1: | |
return -1; | |
case 2: | |
default: | |
return AF_INET6; | |
} | |
} | |
int psircd_server_create(int *fd, const char *address, int port) { | |
int af, sasize; | |
struct in_addr ia; | |
struct in6_addr ia6; | |
struct sockaddr_storage sas; | |
DEBUG("%s:%d", address, port); | |
memset(&sas, 0, sizeof(sas)); | |
af = detect_af(address); | |
if(-1 == af) { | |
ERR("Was unable to detect AF for address; %s", address); | |
return -1; | |
} | |
switch(af) { | |
case AF_INET: | |
DEBUG("AF_INET", 0); | |
if(-1 == inet_pton(af, address, &ia)) { | |
ERR("inet_pton(): %s", errno); | |
return -1; | |
} | |
((struct sockaddr_in*)&sas)->sin_family = AF_INET; | |
((struct sockaddr_in*)&sas)->sin_port = htons(port); | |
((struct sockaddr_in*)&sas)->sin_addr = ia; | |
sasize = sizeof(struct sockaddr_in); | |
break; | |
case AF_INET6: | |
DEBUG("AF_INET6", 0); | |
if(-1 == inet_pton(af, address, &ia6)) { | |
ERR("inet_pton(): %s", errno); | |
return -1; | |
} | |
((struct sockaddr_in6*)&sas)->sin6_family = AF_INET6; | |
((struct sockaddr_in6*)&sas)->sin6_port = htons(port); | |
((struct sockaddr_in6*)&sas)->sin6_addr = ia6; | |
sasize = sizeof(struct sockaddr_in6); | |
break; | |
} | |
*fd = socket(af, SOCK_STREAM, 0); | |
if (-1 == *fd) { | |
ERR("Socket could not be created: %s", strerror(errno)); | |
return errno; | |
} | |
if (0 != setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { | |
ERR("setsockopt(SO_REUSEADDR) failed: %s", strerror(errno)); | |
return errno; | |
} | |
if (0 != bind(*fd, (struct sockaddr *)&sas, sasize)) { | |
ERR("bind() failed: %s", strerror(errno)); | |
return errno; | |
} | |
INFO("Created %s server socket %d, bound to %s:%d", | |
lookup_af(af), *fd, address, port); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment