added qse_setscknonblock(), qse_initsckconn(), qse_finisckconn()
This commit is contained in:
		| @ -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) | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user