#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
+#include <netdb.h>
#include "client.h"
#include "signal.h"
#include "util.h"
{
program_name = argv[0];
+ if (argc < 3)
+ internal_error("missing address or port");
+
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC, // support both IPv4 and IPv6
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = 0,
+ .ai_flags = AI_NUMERICSERV,
+ };
+
+ struct addrinfo *info = NULL;
+
+ int gai_state = getaddrinfo(argv[1], argv[2], &hints, &info);
+
+ if (gai_state != 0)
+ internal_error(gai_strerror(gai_state));
+
Client client = {
.fd = -1,
.map = NULL,
pthread_mutex_init(&client.mtx, NULL);
- client.fd = socket(AF_INET, SOCK_STREAM, 0);
+ client.fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
if (client.fd == -1)
syscall_error("socket");
- if (argc <= 1)
- internal_error("missing address");
-
- struct in_addr addr_buf;
-
- if (inet_aton(argv[1], &addr_buf) == 0)
- internal_error("invalid address");
-
- struct sockaddr_in addr = {
- .sin_family = AF_INET,
- .sin_port = get_port_from_args(argc, argv, 2),
- .sin_addr = addr_buf,
- };
-
- if (connect(client.fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+ if (connect(client.fd, info->ai_addr, info->ai_addrlen) == -1)
syscall_error("connect");
+ freeaddrinfo(info);
+
init_signal_handlers();
client.map = map_create();
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
+#include <netdb.h>
#include "server.h"
#include "signal.h"
#include "util.h"
static void accept_client(Server *srv)
{
- struct sockaddr_in client_addr_buf = {0};
- socklen_t client_addrlen = sizeof(client_addr_buf);
+ struct sockaddr_storage client_address = {0};
+ socklen_t client_addrlen = sizeof(client_address);
- int fd = accept(srv->sockfd, (struct sockaddr *) &client_addr_buf, &client_addrlen);
+ int fd = accept(srv->sockfd, (struct sockaddr *)&client_address, &client_addrlen);
if (fd == -1) {
if (errno == EINTR)
client->state = CS_CREATED;
client->fd = fd;
client->name = NULL;
- client->address = address_string(&client_addr_buf);
+ client->address = address_string((struct sockaddr_in6 *) &client_address);
printf("Connected %s\n", client->address);
{
program_name = argv[0];
+ if (argc < 2)
+ internal_error("missing port");
+
+ struct addrinfo hints = {
+ .ai_family = AF_INET6,
+ .ai_socktype = SOCK_STREAM,
+ .ai_protocol = 0,
+ .ai_flags = AI_NUMERICSERV | AI_PASSIVE,
+ };
+
+ struct addrinfo *info = NULL;
+
+ int gai_state = getaddrinfo(NULL, argv[1], &hints, &info);
+
+ if (gai_state != 0)
+ internal_error(gai_strerror(gai_state));
+
Server server = {
.sockfd = -1,
.map = NULL,
.clients = linked_list_create(),
};
- server.sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ server.sockfd = socket(info->ai_family, info->ai_socktype, 0);
if (server.sockfd == -1)
syscall_error("socket");
- struct sockaddr_in srv_addr = {
- .sin_family = AF_INET,
- .sin_port = get_port_from_args(argc, argv, 1),
- .sin_addr = {.s_addr = INADDR_ANY},
- };
-
int flag = 1;
if (setsockopt(server.sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, 4) == -1)
syscall_error("setsockopt");
- if (bind(server.sockfd, (struct sockaddr *) &srv_addr, sizeof(srv_addr)) == -1)
+ if (bind(server.sockfd, info->ai_addr, info->ai_addrlen) == -1)
syscall_error("bind");
if (listen(server.sockfd, 3) == -1)
syscall_error("listen");
+ freeaddrinfo(info);
+
init_signal_handlers();
server.map = map_create(NULL);
#include <stdio.h>
#include <stdlib.h>
-#include <limits.h>
#include <unistd.h>
#include <string.h>
#include "util.h"
exit(EXIT_FAILURE);
}
-
-unsigned short get_port_from_args(int argc, char **argv, int index)
-{
- if (argc <= index)
- internal_error("missing port");
-
- unsigned int port = atoi(argv[index]);
-
- if (port == 0 || port > USHRT_MAX)
- internal_error("invalid port");
-
- return htons(port);
-}
-
char *read_string(int fd, size_t bufsiz)
{
char buf[bufsiz + 1];
return strdup(buf);
}
-char *address_string(struct sockaddr_in *addr)
+char *address_string(struct sockaddr_in6 *addr)
{
- char *str_addr = inet_ntoa(addr->sin_addr);
- char str_port[5];
- sprintf(str_port, "%d", ntohs(addr->sin_port));
- char *address = malloc(strlen(str_addr) + 1 + strlen(str_port) + 1);
- sprintf(address, "%s:%s", str_addr, str_port);
- return address;
+ char address[INET6_ADDRSTRLEN] = {0};
+ char port[6] = {0};
+
+ if (inet_ntop(addr->sin6_family, &addr->sin6_addr, address, INET6_ADDRSTRLEN) == NULL)
+ perror("inet_ntop");
+ sprintf(port, "%d", ntohs(addr->sin6_port));
+
+ char *result = malloc(strlen(address) + 1 + strlen(port) + 1);
+ sprintf(result, "%s:%s", address, port);
+ return result;
}
void syscall_error(const char *err);
void internal_error(const char *err);
-u16 get_port_from_args(int argc, char **argv, int index);
char *read_string(int fd, size_t bufsiz);
-char *address_string(struct sockaddr_in *addr);
+char *address_string(struct sockaddr_in6 *addr);
#endif