added qse_setscknonblock(), qse_initsckconn(), qse_finisckconn()
This commit is contained in:
parent
07f4118d5d
commit
6353bbfc15
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <qse/types.h>
|
#include <qse/types.h>
|
||||||
#include <qse/macros.h>
|
#include <qse/macros.h>
|
||||||
|
#include <qse/cmn/nwad.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
typedef qse_uintptr_t qse_sck_hnd_t;
|
typedef qse_uintptr_t qse_sck_hnd_t;
|
||||||
@ -87,6 +88,20 @@ QSE_EXPORT void qse_shutsckhnd (
|
|||||||
qse_shutsckhnd_how_t how
|
qse_shutsckhnd_how_t how
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_setscknonblock (
|
||||||
|
qse_sck_hnd_t handle,
|
||||||
|
int enabled
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_initsckconn (
|
||||||
|
qse_sck_hnd_t handle,
|
||||||
|
const qse_nwad_t* nwad
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT int qse_finisckconn (
|
||||||
|
qse_sck_hnd_t handle
|
||||||
|
);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -148,6 +148,123 @@ QSE_INLINE void qse_shutsckhnd (qse_sck_hnd_t handle, qse_shutsckhnd_how_t how)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qse_setscknonblock (qse_sck_hnd_t handle, int enabled)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if (ioctlsocket (handle, FIONBIO, &enabled) == SOCKET_ERROR) return -1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#elif defined(__OS2__)
|
||||||
|
|
||||||
|
if (ioctl (handle, FIONBIO, (char*)&enabled, sizeof(enabled)) <= -1) return -1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#elif defined(__DOS__)
|
||||||
|
|
||||||
|
if (ioctlsocket (handle, FIONBIO, (char*)&enabled) == SOCKET_ERROR) return -1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#elif defined(O_NONBLOCK)
|
||||||
|
|
||||||
|
int flag = fcntl (handle, F_GETFL);
|
||||||
|
if (flag >= 0) flag = fcntl (handle, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK)));
|
||||||
|
if (flag <= -1) return -1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_initsckconn (qse_sck_hnd_t handle, const qse_nwad_t* nwad)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
unsigned long cmd;
|
||||||
|
#else
|
||||||
|
int saved = 0;
|
||||||
|
#endif
|
||||||
|
qse_skad_t skad;
|
||||||
|
int skadlen;
|
||||||
|
|
||||||
|
skadlen = qse_nwadtoskad (nwad, &skad);
|
||||||
|
if (skadlen <= -1) return -1;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
/* switch to the non-blocking mode */
|
||||||
|
cmd = 1;
|
||||||
|
if (ioctlsocket(handle, FIONBIO, &cmd) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
/* error code in WSAGetLastError() */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attempt to connet */
|
||||||
|
n = connect (handle, (struct sockaddr*)&skad, skadlen);
|
||||||
|
if (n == -1 && WSAGetLastError() != WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
/* attemp to restore to the blocking mode upon failure.
|
||||||
|
* there is no guarantee that this was the previous mode. */
|
||||||
|
cmd = 0;
|
||||||
|
ioctlsocket (handle, FIONBIO, &cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* switch to the non-blocking mode */
|
||||||
|
saved = fcntl (handle, F_GETFL, 0);
|
||||||
|
if (saved == -1) return -1;
|
||||||
|
if (fcntl (handle, F_SETFL, saved | O_NONBLOCK) == -1) return -1;
|
||||||
|
|
||||||
|
/* attempt to connet */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n = connect (handle, (struct sockaddr*)&skad, skadlen);
|
||||||
|
}
|
||||||
|
while (n == -1 && errno == EINTR);
|
||||||
|
|
||||||
|
if (n == -1 && errno != EINPROGRESS)
|
||||||
|
{
|
||||||
|
fcntl (handle, F_SETFL, saved); /* restore the flags upon failure */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the socket still remains in the non-blocking mode */
|
||||||
|
return (n == 0)? 1: 0; /* 1: connected, 0: in progress */
|
||||||
|
}
|
||||||
|
|
||||||
|
int qse_finisckconn (qse_sck_hnd_t handle)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
qse_sck_len_t len;
|
||||||
|
|
||||||
|
len = (qse_sck_len_t)QSE_SIZEOF (ret);
|
||||||
|
if (getsockopt (handle, SOL_SOCKET, SO_ERROR, (char*)&ret, &len) == -1) return -1;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (ret == WSAETIMEDOUT)
|
||||||
|
#else
|
||||||
|
if (ret == ETIMEDOUT)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return -1; /* failure - timed out */
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
else if (ret == WSAEWOULDBLOCK)
|
||||||
|
#else
|
||||||
|
else if (ret == EINPROGRESS)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return 0; /* in preogress */
|
||||||
|
}
|
||||||
|
else if (ret != 0)
|
||||||
|
{
|
||||||
|
return -1; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /* connected */
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_sck_hnd_t
|
qse_sck_hnd_t
|
||||||
|
@ -797,54 +797,6 @@ void* qse_httpd_getxtnstd (qse_httpd_t* httpd)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int set_socket_nonblock (qse_httpd_t* httpd, qse_sck_hnd_t fd, int enabled)
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
if (ioctlsocket (fd, FIONBIO, &enabled) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#elif defined(__OS2__)
|
|
||||||
|
|
||||||
if (ioctl (fd, FIONBIO, (char*)&enabled, sizeof(enabled)) <= -1)
|
|
||||||
{
|
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#elif defined(__DOS__)
|
|
||||||
|
|
||||||
if (ioctlsocket (fd, FIONBIO, (char*)&enabled) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#elif defined(O_NONBLOCK)
|
|
||||||
|
|
||||||
int flag = fcntl (fd, F_GETFL);
|
|
||||||
if (flag >= 0) flag = fcntl (fd, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK)));
|
|
||||||
if (flag <= -1)
|
|
||||||
{
|
|
||||||
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
|
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int type, int proto)
|
static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int type, int proto)
|
||||||
{
|
{
|
||||||
qse_sck_hnd_t fd;
|
qse_sck_hnd_t fd;
|
||||||
@ -892,7 +844,11 @@ static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int typ
|
|||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
if (qse_setscknonblock (fd, 1) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(IPPROTO_SCTP)
|
#if defined(IPPROTO_SCTP)
|
||||||
if (proto == IPPROTO_SCTP)
|
if (proto == IPPROTO_SCTP)
|
||||||
@ -906,14 +862,22 @@ static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int typ
|
|||||||
im.sinit_max_instreams = 1;
|
im.sinit_max_instreams = 1;
|
||||||
im.sinit_max_attempts = 1;
|
im.sinit_max_attempts = 1;
|
||||||
|
|
||||||
if (setsockopt (fd, SOL_SCTP, SCTP_INITMSG, &im, QSE_SIZEOF(im)) <= -1) goto oops;
|
if (setsockopt (fd, SOL_SCTP, SCTP_INITMSG, &im, QSE_SIZEOF(im)) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
QSE_MEMSET (&hb, 0, QSE_SIZEOF(hb));
|
QSE_MEMSET (&hb, 0, QSE_SIZEOF(hb));
|
||||||
hb.spp_flags = SPP_HB_ENABLE;
|
hb.spp_flags = SPP_HB_ENABLE;
|
||||||
hb.spp_hbinterval = 5000;
|
hb.spp_hbinterval = 5000;
|
||||||
hb.spp_pathmaxrxt = 1;
|
hb.spp_pathmaxrxt = 1;
|
||||||
|
|
||||||
if (setsockopt (fd, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &hb, QSE_SIZEOF(hb)) <= -1) goto oops;
|
if (setsockopt (fd, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &hb, QSE_SIZEOF(hb)) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1086,7 +1050,11 @@ bind_ok:
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
if (qse_setscknonblock (fd, 1) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
server->handle = fd;
|
server->handle = fd;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1132,7 +1100,11 @@ static int server_accept (
|
|||||||
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
if (qse_setscknonblock (fd, 1) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (qse_skadtonwad (&addr, &client->remote_addr) <= -1)
|
if (qse_skadtonwad (&addr, &client->remote_addr) <= -1)
|
||||||
{
|
{
|
||||||
@ -1456,7 +1428,11 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
|||||||
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (set_socket_nonblock (httpd, fd, 1) <= -1) goto oops;
|
if (qse_setscknonblock (fd, 1) <= -1)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
if (peer->flags & QSE_HTTPD_PEER_SECURE)
|
if (peer->flags & QSE_HTTPD_PEER_SECURE)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user