Commit bd7ae7e2 authored by David Woodhouse's avatar David Woodhouse

Use closesocket() and fix errno handling for MinGW

Based on a patch from Nikos Mavrogiannopoulos.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 76df598b
......@@ -198,3 +198,44 @@ int openconnect__inet_aton(const char *cp, struct in_addr *addr)
return (addr->s_addr == 0xffffffff) ? 0 : 1;
}
#endif
#ifdef _WIN32
int openconnect__win32_neterrno()
{
switch (WSAGetLastError()) {
case WSAEINTR: return EINTR;
case WSAEWOULDBLOCK: return EWOULDBLOCK;
case WSAEINPROGRESS: return EINPROGRESS;
case WSAEALREADY: return EALREADY;
case WSAENOTSOCK: return ENOTSOCK;
case WSAEDESTADDRREQ: return EDESTADDRREQ;
case WSAEMSGSIZE: return EMSGSIZE;
case WSAEPROTOTYPE: return EPROTOTYPE;
case WSAENOPROTOOPT: return ENOPROTOOPT;
case WSAEPROTONOSUPPORT:return EPROTONOSUPPORT;
case WSAEOPNOTSUPP: return EOPNOTSUPP;
case WSAEPFNOSUPPORT: return EAFNOSUPPORT;
case WSAEAFNOSUPPORT: return EAFNOSUPPORT;
case WSAEADDRINUSE: return EADDRINUSE;
case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
case WSAENETDOWN: return ENETDOWN;
case WSAENETUNREACH: return ENETUNREACH;
case WSAENETRESET: return ENETRESET;
case WSAECONNABORTED: return ECONNABORTED;
case WSAECONNRESET: return ECONNRESET;
case WSAENOBUFS: return ENOBUFS;
case WSAEISCONN: return EISCONN;
case WSAENOTCONN: return ENOTCONN;
case WSAETIMEDOUT: return ETIMEDOUT;
case WSAECONNREFUSED: return ECONNREFUSED;
case WSAELOOP: return ELOOP;
case WSAENAMETOOLONG: return ENAMETOOLONG;
case WSAEHOSTUNREACH: return EHOSTUNREACH;
case WSAENOTEMPTY: return ENOTEMPTY;
case WSAEINVAL: return EINVAL;
case WSAEFAULT: return EFAULT;
case 0: return 0;
default: return EIO;
}
}
#endif /* _WIN32 */
......@@ -83,6 +83,10 @@ case $host_os in
AC_DEFINE(HAVE_SUNOS_BROKEN_TIME)
symver_time="openconnect__time;"
;;
*mingw32*|*mingw64*)
AC_MSG_NOTICE([Applying feature macros for MinGW/Windows build])
have_win=yes
;;
*)
# On FreeBSD the only way to get vsyslog() visible is to define
# *nothing*, which makes absolutely everything visible.
......@@ -140,7 +144,12 @@ AS_COMPILER_FLAGS(WFLAGS,
-Wwrite-strings")
AC_SUBST(WFLAGS, [$WFLAGS])
AC_CHECK_FUNC(socket, [], AC_CHECK_LIB(socket, socket, [], AC_ERROR(Cannot find socket() function)))
if test "$have_win" = yes; then
# Checking "properly" for __attribute__((dllimport,stdcall)) functions is non-trivial
LIBS="$LIBS -lws2_32"
else
AC_CHECK_FUNC(socket, [], AC_CHECK_LIB(socket, socket, [], AC_ERROR(Cannot find socket() function)))
fi
have_inet_aton=yes
AC_CHECK_FUNC(inet_aton, [], AC_CHECK_LIB(nsl, inet_aton, [], have_inet_aton=no))
......
......@@ -524,20 +524,20 @@ int connect_dtls_socket(struct openconnect_info *vpninfo)
_("Unknown protocol family %d. Cannot do DTLS\n"),
vpninfo->peer_addr->sa_family);
vpninfo->dtls_attempt_period = 0;
close(dtls_fd);
closesocket(dtls_fd);
return -EINVAL;
}
if (bind(dtls_fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) {
perror(_("Bind UDP socket for DTLS"));
close(dtls_fd);
closesocket(dtls_fd);
return -EINVAL;
}
}
if (connect(dtls_fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) {
perror(_("UDP (DTLS) connect:\n"));
close(dtls_fd);
closesocket(dtls_fd);
return -EINVAL;
}
......@@ -546,7 +546,7 @@ int connect_dtls_socket(struct openconnect_info *vpninfo)
ret = start_dtls_handshake(vpninfo, dtls_fd);
if (ret) {
close(dtls_fd);
closesocket(dtls_fd);
return ret;
}
......@@ -566,7 +566,7 @@ void dtls_close(struct openconnect_info *vpninfo, int kill_handshake_too)
{
if (vpninfo->dtls_ssl) {
DTLS_FREE(vpninfo->dtls_ssl);
close(vpninfo->dtls_fd);
closesocket(vpninfo->dtls_fd);
FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
......@@ -575,7 +575,7 @@ void dtls_close(struct openconnect_info *vpninfo, int kill_handshake_too)
}
if (kill_handshake_too && vpninfo->new_dtls_ssl) {
DTLS_FREE(vpninfo->new_dtls_ssl);
close(vpninfo->new_dtls_fd);
closesocket(vpninfo->new_dtls_fd);
FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_rfds);
FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_efds);
vpninfo->new_dtls_ssl = NULL;
......
......@@ -1862,7 +1862,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
gnutls_free(datum.data);
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -ENOMEM;
}
err = gnutls_x509_crt_list_import(certs, &nr_certs, &datum,
......@@ -1883,7 +1883,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
gnutls_strerror(err));
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
}
......@@ -1899,7 +1899,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
vpninfo->cafile, gnutls_strerror(err));
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
}
......@@ -1911,7 +1911,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
_("Loading certificate failed. Aborting.\n"));
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return err;
}
}
......@@ -1937,7 +1937,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
gnutls_strerror(err));
gnutls_deinit(vpninfo->https_sess);
vpninfo->https_sess = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EIO;
}
......@@ -1967,7 +1967,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
gnutls_deinit(vpninfo->https_sess);
vpninfo->https_sess = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EINTR;
}
} else if (err == GNUTLS_E_INTERRUPTED || gnutls_error_is_fatal(err)) {
......@@ -1975,7 +1975,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
gnutls_strerror(err));
gnutls_deinit(vpninfo->https_sess);
vpninfo->https_sess = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EIO;
} else {
/* non-fatal error or warning. Ignore it and continue */
......@@ -2004,7 +2004,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
vpninfo->https_sess = NULL;
}
if (vpninfo->ssl_fd != -1) {
close(vpninfo->ssl_fd);
closesocket(vpninfo->ssl_fd);
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_rfds);
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
......
......@@ -369,6 +369,14 @@ void openconnect__unsetenv(const char *name);
int openconnect__inet_aton(const char *cp, struct in_addr *addr);
#endif
#ifdef _WIN32
#define neterrno openconnect__win32_neterrno
int openconnect__win32_neterrno();
#else
#define neterrno() errno
#define closesocket close
#endif
/* I always coded as if it worked like this. Now it does. */
#define realloc_inplace(p, size) do { \
void *__realloc_old = p; \
......
......@@ -1283,7 +1283,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
_("Loading certificate failed. Aborting.\n"));
SSL_CTX_free(vpninfo->https_ctx);
vpninfo->https_ctx = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return err;
}
check_certificate_expiry(vpninfo);
......@@ -1316,7 +1316,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
if (!b) {
SSL_CTX_free(vpninfo->https_ctx);
vpninfo->https_ctx = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
......@@ -1330,7 +1330,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
openconnect_report_ssl_errors(vpninfo);
SSL_CTX_free(vpninfo->https_ctx);
vpninfo->https_ctx = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -ENOENT;
}
......@@ -1354,7 +1354,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
openconnect_report_ssl_errors(vpninfo);
SSL_CTX_free(vpninfo->https_ctx);
vpninfo->https_ctx = NULL;
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
}
......@@ -1386,7 +1386,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure\n"));
openconnect_report_ssl_errors(vpninfo);
SSL_free(https_ssl);
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
......@@ -1395,14 +1395,14 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
if (is_cancel_pending(vpninfo, &rd_set)) {
vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
SSL_free(https_ssl);
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
}
if (verify_peer(vpninfo, https_ssl)) {
SSL_free(https_ssl);
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
......@@ -1430,7 +1430,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
vpninfo->https_ssl = NULL;
}
if (vpninfo->ssl_fd != -1) {
close(vpninfo->ssl_fd);
closesocket(vpninfo->ssl_fd);
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_rfds);
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_wfds);
FD_CLR(vpninfo->ssl_fd, &vpninfo->select_efds);
......
......@@ -66,7 +66,7 @@ static int cancellable_connect(struct openconnect_info *vpninfo, int sockfd,
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, sockfd);
if (connect(sockfd, addr, addrlen) < 0 && errno != EINPROGRESS)
if (connect(sockfd, addr, addrlen) < 0 && neterrno() != EINPROGRESS)
return -1;
do {
......@@ -119,7 +119,7 @@ int connect_https_socket(struct openconnect_info *vpninfo)
vpninfo->hostname);
}
if (ssl_sock >= 0)
close(ssl_sock);
closesocket(ssl_sock);
return -EINVAL;
}
} else {
......@@ -242,7 +242,7 @@ int connect_https_socket(struct openconnect_info *vpninfo)
if (!vpninfo->peer_addr) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to allocate sockaddr storage\n"));
close(ssl_sock);
closesocket(ssl_sock);
return -ENOMEM;
}
vpninfo->peer_addrlen = rp->ai_addrlen;
......@@ -266,7 +266,7 @@ int connect_https_socket(struct openconnect_info *vpninfo)
}
break;
}
close(ssl_sock);
closesocket(ssl_sock);
ssl_sock = -1;
}
freeaddrinfo(result);
......@@ -282,7 +282,7 @@ int connect_https_socket(struct openconnect_info *vpninfo)
if (vpninfo->proxy) {
err = process_proxy(vpninfo, ssl_sock);
if (err) {
close(ssl_sock);
closesocket(ssl_sock);
return err;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment