mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
fix #503 recv errors in httpd.c; define CLOSESOCKET, IOCTLSOCKET
This commit is contained in:
62
lib/httpd.c
62
lib/httpd.c
@@ -39,7 +39,6 @@ static const char *typename[] = {
|
|||||||
|
|
||||||
struct http_connection_s {
|
struct http_connection_s {
|
||||||
int connected;
|
int connected;
|
||||||
|
|
||||||
int socket_fd;
|
int socket_fd;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
connection_type_t type;
|
connection_type_t type;
|
||||||
@@ -50,7 +49,6 @@ typedef struct http_connection_s http_connection_t;
|
|||||||
struct httpd_s {
|
struct httpd_s {
|
||||||
logger_t *logger;
|
logger_t *logger;
|
||||||
httpd_callbacks_t callbacks;
|
httpd_callbacks_t callbacks;
|
||||||
|
|
||||||
int max_connections;
|
int max_connections;
|
||||||
int open_connections;
|
int open_connections;
|
||||||
http_connection_t *connections;
|
http_connection_t *connections;
|
||||||
@@ -192,17 +190,20 @@ httpd_destroy(httpd_t *httpd)
|
|||||||
{
|
{
|
||||||
if (httpd) {
|
if (httpd) {
|
||||||
httpd_stop(httpd);
|
httpd_stop(httpd);
|
||||||
|
|
||||||
free(httpd->connections);
|
free(httpd->connections);
|
||||||
free(httpd);
|
free(httpd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
httpd_remove_connection(httpd_t *httpd, http_connection_t *connection)
|
httpd_remove_connection(httpd_t *httpd, http_connection_t *connection, int sock_err)
|
||||||
{
|
{
|
||||||
int socket_fd = connection->socket_fd;
|
int socket_fd = connection->socket_fd;
|
||||||
connection->socket_fd = 0;
|
connection->socket_fd = 0;
|
||||||
|
if (sock_err) {
|
||||||
|
logger_log(httpd->logger, LOGGER_INFO, "httpd: recv error %d on socket %d: %s",
|
||||||
|
sock_err, socket_fd, SOCKET_ERROR_STRING(sock_err));
|
||||||
|
}
|
||||||
if (connection->request) {
|
if (connection->request) {
|
||||||
http_request_destroy(connection->request);
|
http_request_destroy(connection->request);
|
||||||
connection->request = NULL;
|
connection->request = NULL;
|
||||||
@@ -214,10 +215,12 @@ httpd_remove_connection(httpd_t *httpd, http_connection_t *connection)
|
|||||||
connection->user_data = NULL;
|
connection->user_data = NULL;
|
||||||
}
|
}
|
||||||
if (socket_fd) {
|
if (socket_fd) {
|
||||||
|
if (!sock_err) {
|
||||||
shutdown(socket_fd, SHUT_WR);
|
shutdown(socket_fd, SHUT_WR);
|
||||||
int ret = closesocket(socket_fd);
|
}
|
||||||
|
int ret = CLOSESOCKET(socket_fd);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
logger_log(httpd->logger, LOGGER_ERR, "httpd error in closesocket (close): %d %s", errno, strerror(errno));
|
logger_log(httpd->logger, LOGGER_ERR, "httpd error in CLOSESOCKET: %d %s", errno, SOCKET_ERROR_STRING(errno));
|
||||||
} else {
|
} else {
|
||||||
logger_log(httpd->logger, LOGGER_INFO, "Connection closed on socket %d", socket_fd);
|
logger_log(httpd->logger, LOGGER_INFO, "Connection closed on socket %d", socket_fd);
|
||||||
}
|
}
|
||||||
@@ -284,7 +287,7 @@ httpd_accept_connection(httpd_t *httpd, int server_fd, int is_ipv6)
|
|||||||
ret = getsockname(fd, (struct sockaddr *)&local_saddr, &local_saddrlen);
|
ret = getsockname(fd, (struct sockaddr *)&local_saddr, &local_saddrlen);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
shutdown(fd, SHUT_RDWR);
|
shutdown(fd, SHUT_RDWR);
|
||||||
closesocket(fd);
|
CLOSESOCKET(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +306,7 @@ httpd_accept_connection(httpd_t *httpd, int server_fd, int is_ipv6)
|
|||||||
ret = httpd_add_connection(httpd, fd, local, local_len, remote, remote_len, local_zone_id);
|
ret = httpd_add_connection(httpd, fd, local, local_len, remote, remote_len, local_zone_id);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
shutdown(fd, SHUT_RDWR);
|
shutdown(fd, SHUT_RDWR);
|
||||||
closesocket(fd);
|
CLOSESOCKET(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -321,7 +324,7 @@ httpd_remove_known_connections(httpd_t *httpd) {
|
|||||||
if (!connection->connected || connection->type == CONNECTION_TYPE_UNKNOWN) {
|
if (!connection->connected || connection->type == CONNECTION_TYPE_UNKNOWN) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +335,7 @@ httpd_remove_connections_by_type(httpd_t *httpd, connection_type_t type) {
|
|||||||
if (!connection->connected || connection->type != type) {
|
if (!connection->connected || connection->type != type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,18 +481,16 @@ httpd_thread(void *arg)
|
|||||||
if (!connection->socket_fd) {
|
if (!connection->socket_fd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = recv(connection->socket_fd, buffer + readstart, sizeof(buffer) - 1 - readstart, 0);
|
ret = recv(connection->socket_fd, buffer + readstart, sizeof(buffer) - readstart, 0);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
logger_log(httpd->logger, LOGGER_DEBUG, "client closed connection on socket %d",
|
logger_log(httpd->logger, LOGGER_DEBUG, "client closed connection on socket %d",
|
||||||
connection->socket_fd);
|
connection->socket_fd);
|
||||||
break;
|
break;
|
||||||
} else if (ret == -1) {
|
} else if (ret == -1) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == SOCKET_ERRORNAME(EAGAIN) || errno == SOCKET_ERRORNAME(EWOULDBLOCK) || errno == SOCKET_ERRORNAME(EINTR)) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
int sock_err = SOCKET_GET_ERROR();
|
httpd_remove_connection(httpd, connection, SOCKET_GET_ERROR());
|
||||||
logger_log(httpd->logger, LOGGER_ERR, "httpd: recv error %d on socket %d: %s",
|
|
||||||
sock_err, connection->socket_fd, SOCKET_ERROR_STRING(sock_err));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -506,10 +507,17 @@ httpd_thread(void *arg)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (connection->socket_fd) {
|
if (connection->socket_fd) {
|
||||||
ret = recv(connection->socket_fd, buffer, sizeof(buffer) - 1, 0);
|
ret = recv(connection->socket_fd, buffer, sizeof(buffer), 0);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
continue;
|
continue;
|
||||||
|
} else if (ret == -1) {
|
||||||
|
if (errno == SOCKET_ERRORNAME(EAGAIN) || errno == SOCKET_ERRORNAME(EWOULDBLOCK) || errno == SOCKET_ERRORNAME(EINTR)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
httpd_remove_connection(httpd, connection, SOCKET_GET_ERROR());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* connection was recently removed */
|
/* connection was recently removed */
|
||||||
@@ -526,7 +534,7 @@ httpd_thread(void *arg)
|
|||||||
" on socket %d:\n%s\n", connection->socket_fd, buffer);
|
" on socket %d:\n%s\n", connection->socket_fd, buffer);
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -540,7 +548,7 @@ httpd_thread(void *arg)
|
|||||||
http_request_get_error_description(connection->request),
|
http_request_get_error_description(connection->request),
|
||||||
data);
|
data);
|
||||||
free (data);
|
free (data);
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,7 +589,7 @@ httpd_thread(void *arg)
|
|||||||
|
|
||||||
if (http_response_get_disconnect(response)) {
|
if (http_response_get_disconnect(response)) {
|
||||||
logger_log(httpd->logger, LOGGER_INFO, "Disconnecting on software request");
|
logger_log(httpd->logger, LOGGER_INFO, "Disconnecting on software request");
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger_log(httpd->logger, LOGGER_WARNING, "httpd didn't get response");
|
logger_log(httpd->logger, LOGGER_WARNING, "httpd didn't get response");
|
||||||
@@ -601,18 +609,18 @@ httpd_thread(void *arg)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logger_log(httpd->logger, LOGGER_INFO, "Removing connection for socket %d", connection->socket_fd);
|
logger_log(httpd->logger, LOGGER_INFO, "Removing connection for socket %d", connection->socket_fd);
|
||||||
httpd_remove_connection(httpd, connection);
|
httpd_remove_connection(httpd, connection, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close server sockets since they are not used any more */
|
/* Close server sockets since they are not used any more */
|
||||||
if (httpd->server_fd4 != -1) {
|
if (httpd->server_fd4 != -1) {
|
||||||
shutdown(httpd->server_fd4, SHUT_RDWR);
|
shutdown(httpd->server_fd4, SHUT_RDWR);
|
||||||
closesocket(httpd->server_fd4);
|
CLOSESOCKET(httpd->server_fd4);
|
||||||
httpd->server_fd4 = -1;
|
httpd->server_fd4 = -1;
|
||||||
}
|
}
|
||||||
if (httpd->server_fd6 != -1) {
|
if (httpd->server_fd6 != -1) {
|
||||||
shutdown(httpd->server_fd6, SHUT_RDWR);
|
shutdown(httpd->server_fd6, SHUT_RDWR);
|
||||||
closesocket(httpd->server_fd6);
|
CLOSESOCKET(httpd->server_fd6);
|
||||||
httpd->server_fd6 = -1;
|
httpd->server_fd6 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,15 +663,15 @@ httpd_start(httpd_t *httpd, unsigned short *port)
|
|||||||
|
|
||||||
if (httpd->server_fd4 != -1 && listen(httpd->server_fd4, backlog) == -1) {
|
if (httpd->server_fd4 != -1 && listen(httpd->server_fd4, backlog) == -1) {
|
||||||
logger_log(httpd->logger, LOGGER_ERR, "Error listening to IPv4 socket");
|
logger_log(httpd->logger, LOGGER_ERR, "Error listening to IPv4 socket");
|
||||||
closesocket(httpd->server_fd4);
|
CLOSESOCKET(httpd->server_fd4);
|
||||||
closesocket(httpd->server_fd6);
|
CLOSESOCKET(httpd->server_fd6);
|
||||||
MUTEX_UNLOCK(httpd->run_mutex);
|
MUTEX_UNLOCK(httpd->run_mutex);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (httpd->server_fd6 != -1 && listen(httpd->server_fd6, backlog) == -1) {
|
if (httpd->server_fd6 != -1 && listen(httpd->server_fd6, backlog) == -1) {
|
||||||
logger_log(httpd->logger, LOGGER_ERR, "Error listening to IPv6 socket");
|
logger_log(httpd->logger, LOGGER_ERR, "Error listening to IPv6 socket");
|
||||||
closesocket(httpd->server_fd4);
|
CLOSESOCKET(httpd->server_fd4);
|
||||||
closesocket(httpd->server_fd6);
|
CLOSESOCKET(httpd->server_fd6);
|
||||||
MUTEX_UNLOCK(httpd->run_mutex);
|
MUTEX_UNLOCK(httpd->run_mutex);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ netutils_init_socket(unsigned short *port, int use_ipv6, int use_udp)
|
|||||||
cleanup:
|
cleanup:
|
||||||
ret = SOCKET_GET_ERROR();
|
ret = SOCKET_GET_ERROR();
|
||||||
if (server_fd != -1) {
|
if (server_fd != -1) {
|
||||||
closesocket(server_fd);
|
CLOSESOCKET(server_fd);
|
||||||
}
|
}
|
||||||
SOCKET_SET_ERROR(ret);
|
SOCKET_SET_ERROR(ret);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ raop_ntp_init_socket(raop_ntp_t *raop_ntp, int use_ipv6)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sockets_cleanup:
|
sockets_cleanup:
|
||||||
if (tsock != -1) closesocket(tsock);
|
if (tsock != -1) CLOSESOCKET(tsock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,13 +252,11 @@ static void
|
|||||||
raop_ntp_flush_socket(int fd)
|
raop_ntp_flush_socket(int fd)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define IOCTL ioctlsocket
|
|
||||||
u_long bytes_available = 0;
|
u_long bytes_available = 0;
|
||||||
#else
|
#else
|
||||||
#define IOCTL ioctl
|
|
||||||
int bytes_available = 0;
|
int bytes_available = 0;
|
||||||
#endif
|
#endif
|
||||||
while (IOCTL(fd, FIONREAD, &bytes_available) == 0 && bytes_available > 0)
|
while (IOCTLSOCKET(fd, FIONREAD, &bytes_available) == 0 && bytes_available > 0)
|
||||||
{
|
{
|
||||||
// We are guaranteed that we won't block, because bytes are available.
|
// We are guaranteed that we won't block, because bytes are available.
|
||||||
// Read 1 byte. Extra bytes in the datagram will be discarded.
|
// Read 1 byte. Extra bytes in the datagram will be discarded.
|
||||||
@@ -464,7 +462,7 @@ raop_ntp_stop(raop_ntp_t *raop_ntp)
|
|||||||
THREAD_JOIN(raop_ntp->thread);
|
THREAD_JOIN(raop_ntp->thread);
|
||||||
|
|
||||||
if (raop_ntp->tsock != -1) {
|
if (raop_ntp->tsock != -1) {
|
||||||
closesocket(raop_ntp->tsock);
|
CLOSESOCKET(raop_ntp->tsock);
|
||||||
raop_ntp->tsock = -1;
|
raop_ntp->tsock = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -270,8 +270,8 @@ raop_rtp_init_sockets(raop_rtp_t *raop_rtp, int use_ipv6)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sockets_cleanup:
|
sockets_cleanup:
|
||||||
if (csock != -1) closesocket(csock);
|
if (csock != -1) CLOSESOCKET(csock);
|
||||||
if (dsock != -1) closesocket(dsock);
|
if (dsock != -1) CLOSESOCKET(dsock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,11 +832,11 @@ raop_rtp_stop(raop_rtp_t *raop_rtp)
|
|||||||
THREAD_JOIN(raop_rtp->thread);
|
THREAD_JOIN(raop_rtp->thread);
|
||||||
|
|
||||||
if (raop_rtp->csock != -1) {
|
if (raop_rtp->csock != -1) {
|
||||||
closesocket(raop_rtp->csock);
|
CLOSESOCKET(raop_rtp->csock);
|
||||||
raop_rtp->csock = -1;
|
raop_rtp->csock = -1;
|
||||||
}
|
}
|
||||||
if (raop_rtp->dsock != -1) {
|
if (raop_rtp->dsock != -1) {
|
||||||
closesocket(raop_rtp->dsock);
|
CLOSESOCKET(raop_rtp->dsock);
|
||||||
raop_rtp->dsock = -1;
|
raop_rtp->dsock = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -840,7 +840,7 @@ raop_rtp_mirror_thread(void *arg)
|
|||||||
}
|
}
|
||||||
/* Close the stream file descriptor */
|
/* Close the stream file descriptor */
|
||||||
if (stream_fd != -1) {
|
if (stream_fd != -1) {
|
||||||
closesocket(stream_fd);
|
CLOSESOCKET(stream_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure running reflects the actual state
|
// Ensure running reflects the actual state
|
||||||
@@ -854,7 +854,7 @@ raop_rtp_mirror_thread(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unsupported_codec) {
|
if (unsupported_codec) {
|
||||||
closesocket(raop_rtp_mirror->mirror_data_sock);
|
CLOSESOCKET(raop_rtp_mirror->mirror_data_sock);
|
||||||
raop_rtp_mirror_stop(raop_rtp_mirror);
|
raop_rtp_mirror_stop(raop_rtp_mirror);
|
||||||
raop_rtp_mirror->callbacks.video_reset(raop_rtp_mirror->callbacks.cls, RESET_TYPE_RTP_SHUTDOWN);
|
raop_rtp_mirror->callbacks.video_reset(raop_rtp_mirror->callbacks.cls, RESET_TYPE_RTP_SHUTDOWN);
|
||||||
}
|
}
|
||||||
@@ -888,7 +888,7 @@ raop_rtp_mirror_init_socket(raop_rtp_mirror_t *raop_rtp_mirror, int use_ipv6)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
sockets_cleanup:
|
sockets_cleanup:
|
||||||
if (dsock != -1) closesocket(dsock);
|
if (dsock != -1) CLOSESOCKET(dsock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,7 +947,7 @@ void raop_rtp_mirror_stop(raop_rtp_mirror_t *raop_rtp_mirror) {
|
|||||||
THREAD_JOIN(raop_rtp_mirror->thread_mirror);
|
THREAD_JOIN(raop_rtp_mirror->thread_mirror);
|
||||||
|
|
||||||
if (raop_rtp_mirror->mirror_data_sock != -1) {
|
if (raop_rtp_mirror->mirror_data_sock != -1) {
|
||||||
closesocket(raop_rtp_mirror->mirror_data_sock);
|
CLOSESOCKET(raop_rtp_mirror->mirror_data_sock);
|
||||||
raop_rtp_mirror->mirror_data_sock = -1;
|
raop_rtp_mirror->mirror_data_sock = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,12 @@ typedef int socklen_t;
|
|||||||
|
|
||||||
#define WSAEAGAIN WSAEWOULDBLOCK
|
#define WSAEAGAIN WSAEWOULDBLOCK
|
||||||
#define WSAENOMEM WSA_NOT_ENOUGH_MEMORY
|
#define WSAENOMEM WSA_NOT_ENOUGH_MEMORY
|
||||||
|
#define CLOSESOCKET closesocket
|
||||||
|
#define IOCTLSOCKET ioctlsocket
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define closesocket close
|
#define CLOSESOCKET close
|
||||||
#define ioctlsocket ioctl
|
#define IOCTLSOCKET ioctl
|
||||||
|
|
||||||
#define SOCKET_GET_ERROR() (errno)
|
#define SOCKET_GET_ERROR() (errno)
|
||||||
#define SOCKET_SET_ERROR(value) (errno = (value))
|
#define SOCKET_SET_ERROR(value) (errno = (value))
|
||||||
|
|||||||
Reference in New Issue
Block a user