Skip to content

Commit

Permalink
Factor out udp_connect() helper function
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jan 26, 2015
1 parent 8721d40 commit c2b6cb7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 54 deletions.
57 changes: 3 additions & 54 deletions dtls.c
Expand Up @@ -457,7 +457,7 @@ void dtls_shutdown(struct openconnect_info *vpninfo)

static int connect_dtls_socket(struct openconnect_info *vpninfo)
{
int dtls_fd, ret, sndbuf;
int dtls_fd, ret;

/* Sanity check for the removal of new_dtls_{fd,ssl} */
if (vpninfo->dtls_fd != -1) {
Expand Down Expand Up @@ -486,61 +486,10 @@ static int connect_dtls_socket(struct openconnect_info *vpninfo)
return -EINVAL;
}

dtls_fd = socket(vpninfo->peer_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (dtls_fd < 0) {
vpn_perror(vpninfo, _("Open UDP socket for DTLS:"));
dtls_fd = udp_connect(vpninfo);
if (dtls_fd < 0)
return -EINVAL;
}
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, dtls_fd);

sndbuf = vpninfo->ip_info.mtu * 2;
setsockopt(dtls_fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf, sizeof(sndbuf));

if (vpninfo->dtls_local_port) {
union {
struct sockaddr_in in;
struct sockaddr_in6 in6;
} dtls_bind_addr;
int dtls_bind_addrlen;
memset(&dtls_bind_addr, 0, sizeof(dtls_bind_addr));

if (vpninfo->peer_addr->sa_family == AF_INET) {
struct sockaddr_in *addr = &dtls_bind_addr.in;
dtls_bind_addrlen = sizeof(*addr);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = INADDR_ANY;
addr->sin_port = htons(vpninfo->dtls_local_port);
} else if (vpninfo->peer_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *addr = &dtls_bind_addr.in6;
dtls_bind_addrlen = sizeof(*addr);
addr->sin6_family = AF_INET6;
addr->sin6_addr = in6addr_any;
addr->sin6_port = htons(vpninfo->dtls_local_port);
} else {
vpn_progress(vpninfo, PRG_ERR,
_("Unknown protocol family %d. Cannot do DTLS\n"),
vpninfo->peer_addr->sa_family);
vpninfo->dtls_attempt_period = 0;
closesocket(dtls_fd);
return -EINVAL;
}

if (bind(dtls_fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) {
vpn_perror(vpninfo, _("Bind UDP socket for DTLS"));
closesocket(dtls_fd);
return -EINVAL;
}
}

if (connect(dtls_fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) {
vpn_perror(vpninfo, _("UDP (DTLS) connect:\n"));
closesocket(dtls_fd);
return -EINVAL;
}

set_fd_cloexec(dtls_fd);
set_sock_nonblock(dtls_fd);

ret = start_dtls_handshake(vpninfo, dtls_fd);
if (ret) {
Expand Down
1 change: 1 addition & 0 deletions openconnect-internal.h
Expand Up @@ -704,6 +704,7 @@ int openconnect_open_utf8(struct openconnect_info *vpninfo,
FILE *openconnect_fopen_utf8(struct openconnect_info *vpninfo,
const char *fname, const char *mode);
int udp_sockaddr(struct openconnect_info *vpninfo, int port);
int udp_connect(struct openconnect_info *vpninfo);

void openconnect_clear_cookies(struct openconnect_info *vpninfo);

Expand Down
63 changes: 63 additions & 0 deletions ssl.c
Expand Up @@ -822,3 +822,66 @@ int udp_sockaddr(struct openconnect_info *vpninfo, int port)

return 0;
}

int udp_connect(struct openconnect_info *vpninfo)
{
int fd, sndbuf;

fd = socket(vpninfo->peer_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
vpn_perror(vpninfo, _("Open UDP socket"));
return -EINVAL;
}
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, fd);

sndbuf = vpninfo->ip_info.mtu * 2;
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf, sizeof(sndbuf));

if (vpninfo->dtls_local_port) {
union {
struct sockaddr_in in;
struct sockaddr_in6 in6;
} dtls_bind_addr;
int dtls_bind_addrlen;
memset(&dtls_bind_addr, 0, sizeof(dtls_bind_addr));

if (vpninfo->peer_addr->sa_family == AF_INET) {
struct sockaddr_in *addr = &dtls_bind_addr.in;
dtls_bind_addrlen = sizeof(*addr);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = INADDR_ANY;
addr->sin_port = htons(vpninfo->dtls_local_port);
} else if (vpninfo->peer_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *addr = &dtls_bind_addr.in6;
dtls_bind_addrlen = sizeof(*addr);
addr->sin6_family = AF_INET6;
addr->sin6_addr = in6addr_any;
addr->sin6_port = htons(vpninfo->dtls_local_port);
} else {
vpn_progress(vpninfo, PRG_ERR,
_("Unknown protocol family %d. Cannot use UDP transport\n"),
vpninfo->peer_addr->sa_family);
vpninfo->dtls_attempt_period = 0;
closesocket(fd);
return -EINVAL;
}

if (bind(fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) {
vpn_perror(vpninfo, _("Bind UDP socket"));
closesocket(fd);
return -EINVAL;
}
}

if (connect(fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) {
vpn_perror(vpninfo, _("Connect UDP socket\n"));
closesocket(fd);
return -EINVAL;
}

set_fd_cloexec(fd);
set_sock_nonblock(fd);

return fd;
}

0 comments on commit c2b6cb7

Please sign in to comment.