1#include <dtls.h>2#include <errno.h>3#include <netdb.h>4#include <stdlib.h>5#include <assert.h>67#include <sys/types.h>8#include <sys/socket.h>910#include "dat.h"1112static socklen_t13str2addr(char *host, char *port, struct sockaddr *dest)14{15 socklen_t len;16 struct addrinfo hint, *res, *r;1718 memset(&hint, '\0', sizeof(hint));19 hint.ai_family = AF_UNSPEC;20 hint.ai_socktype = SOCK_DGRAM;2122 if (getaddrinfo(host, port, &hint, &res)) {23 errno = EAFNOSUPPORT;24 return 0;25 }2627 len = 0;28 for (r = res; r != NULL; r = r->ai_next) {29 switch (r->ai_family) {30 case AF_INET6:31 case AF_INET:32 len = r->ai_addrlen;33 memcpy(dest, r->ai_addr, len);34 goto ret;35 default:36 errno = EADDRNOTAVAIL;37 goto ret;38 }39 }4041 errno = EADDRNOTAVAIL;42ret:43 freeaddrinfo(res);44 return len;45}4647static int48sock(char *host, char *port, struct sockaddr *addr, socklen_t *alen)49{50 int fd;5152 /* From getaddrinfo(3)53 * The nodename and servname arguments are either null54 * pointers or pointers to null-terminated strings. One or55 * both of these two arguments shall be supplied by the56 * application as a non-null pointer.57 */58 assert(host != NULL || port != NULL);59 if (!(*alen = str2addr(host, port, addr)))60 return -1;6162 if ((fd = socket(addr->sa_family, SOCK_DGRAM, 0)) == -1)63 return -1;6465 return fd;66}6768int69usock(char *host, char *port, sockop op)70{71 int fd;72 socklen_t alen;73 struct sockaddr_storage addr;7475 if ((fd = sock(host, port, (struct sockaddr*)&addr, &alen)) == -1)76 return -1;7778 switch (op) {79 case SOCK_CONN:80 if ((connect(fd, (struct sockaddr*)&addr, alen)) == -1)81 return -1;82 break;83 case SOCK_BIND:84 if ((bind(fd, (struct sockaddr*)&addr, alen)) == -1)85 return -1;86 break;87 default: /* unknown operation */88 errno = EINVAL;89 return -1;90 }9192 return fd;93}9495dtls_context_t*96dsock(char *host, char *port, unsigned char *id,97 unsigned char *key, int ufd, sockop op)98{99 int fd;100 struct dctx *dctx;101 dtls_context_t *ctx;102103 if (!(dctx = malloc(sizeof(*dctx))))104 return NULL;105106 memset(&dsess, '\0', sizeof(dsess));107 if ((fd = sock(host, port, &dsess.addr.sa, &dsess.size)) == -1)108 return NULL;109110 dctx->ufd = ufd;111 dctx->dfd = fd;112 dctx->key = key;113 dctx->id = id;114115 if (!(ctx = dtls_new_context(dctx))) {116 errno = ENOMEM;117 return NULL;118 }119120 dtls_set_handler(ctx, &dtlscb);121 switch (op) {122 case SOCK_CONN:123 if (dtls_connect(ctx, &dsess) < 0) {124 errno = ECONNREFUSED;125 return NULL;126 }127 break;128 case SOCK_BIND:129 if (bind(dctx->dfd, (struct sockaddr*)&dsess.addr.sa, dsess.size) == -1)130 return NULL;131 break;132 default: /* unknown operation */133 errno = EINVAL;134 return NULL;135 }136137 return ctx;138}