Select port in mud_create() and add mud_set_key()

This commit is contained in:
angt
2016-03-01 15:08:28 +00:00
parent a1ce4740b4
commit fc8e97caef
2 changed files with 60 additions and 38 deletions

93
mud.c
View File

@@ -416,58 +416,78 @@ int mud_bind (struct mud *mud, const char *name)
return 0; return 0;
} }
struct mud *mud_create (const unsigned char *key, size_t key_size) int mud_set_key (struct mud *mud, unsigned char *key, size_t size)
{ {
if (key_size != crypto_aead_aes256gcm_KEYBYTES) { if (size != crypto_aead_aes256gcm_KEYBYTES) {
errno = EINVAL; errno = EINVAL;
return NULL; return -1;
} }
crypto_aead_aes256gcm_beforenm(&mud->crypto.key, key);
return 0;
}
struct mud *mud_create (const char *port)
{
struct mud *mud = calloc(1, sizeof(struct mud)); struct mud *mud = calloc(1, sizeof(struct mud));
if (!mud) if (!mud)
return NULL; return NULL;
mud->fd = socket(AF_INET6, SOCK_DGRAM, 0); mud->fd = -1;
if (mud->fd == -1) struct addrinfo *p, *ai = mud_addrinfo(NULL, port, AI_PASSIVE|AI_NUMERICSERV);
goto fail;
if (mud_sso_int(mud->fd, SOL_SOCKET, SO_REUSEADDR, 1) || if (!ai) {
mud_sso_int(mud->fd, IPPROTO_IP, IP_PKTINFO, 1) || mud_delete(mud);
mud_sso_int(mud->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) || return NULL;
mud_sso_int(mud->fd, IPPROTO_IPV6, IPV6_V6ONLY, 0)) }
goto fail;
for (p = ai; p; p = p->ai_next) {
if (p->ai_family != AF_INET6)
continue;
if (!p->ai_addr)
continue;
int fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (fd == -1)
continue;
if (mud_sso_int(fd, SOL_SOCKET, SO_REUSEADDR, 1) ||
mud_sso_int(fd, IPPROTO_IP, IP_PKTINFO, 1) ||
mud_sso_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) ||
mud_sso_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, 0) ||
mud_set_nonblock(fd) ||
bind(fd, p->ai_addr, p->ai_addrlen)) {
close(fd);
continue;
}
mud->fd = fd;
break;
}
freeaddrinfo(ai);
if (mud->fd == -1) {
mud_delete(mud);
return NULL;
}
mud->tx.packet = calloc(256, sizeof(struct packet)); mud->tx.packet = calloc(256, sizeof(struct packet));
mud->rx.packet = calloc(256, sizeof(struct packet)); mud->rx.packet = calloc(256, sizeof(struct packet));
if (!mud->tx.packet || !mud->rx.packet) if (!mud->tx.packet || !mud->rx.packet) {
goto fail; mud_delete(mud);
return NULL;
}
struct sockaddr_in6 sin6 = {
.sin6_family = AF_INET6,
.sin6_port = htons(5000),
};
mud_set_nonblock(mud->fd);
if (bind(mud->fd, (struct sockaddr *)&sin6, sizeof(sin6)))
goto fail;
crypto_aead_aes256gcm_beforenm(&mud->crypto.key, key);
mud->base = mud_now(mud); mud->base = mud_now(mud);
return mud; return mud;
fail:
if (mud) {
int err = errno;
mud_delete(mud);
errno = err;
}
return NULL;
} }
int mud_get_fd (struct mud *mud) int mud_get_fd (struct mud *mud)
@@ -485,20 +505,21 @@ void mud_delete (struct mud *mud)
while (mud->sock) { while (mud->sock) {
struct sock *sock = mud->sock; struct sock *sock = mud->sock;
mud->sock = sock->next; mud->sock = sock->next;
free(sock); free(sock);
} }
while (mud->path) { while (mud->path) {
struct path *path = mud->path; struct path *path = mud->path;
mud->path = path->next; mud->path = path->next;
free(path); free(path);
} }
if (mud->fd != -1) if (mud->fd != -1) {
int err = errno;
close(mud->fd); close(mud->fd);
errno = err;
}
free(mud); free(mud);
} }

3
mud.h
View File

@@ -4,9 +4,10 @@
struct mud; struct mud;
struct mud *mud_create (const unsigned char *, size_t); struct mud *mud_create (const char *);
void mud_delete (struct mud *); void mud_delete (struct mud *);
int mud_set_key (struct mud *, unsigned char *, size_t);
int mud_get_fd (struct mud *); int mud_get_fd (struct mud *);
int mud_bind (struct mud *, const char *); int mud_bind (struct mud *, const char *);