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:
64
lib/httpd.c
64
lib/httpd.c
@@ -39,7 +39,6 @@ static const char *typename[] = {
|
||||
|
||||
struct http_connection_s {
|
||||
int connected;
|
||||
|
||||
int socket_fd;
|
||||
void *user_data;
|
||||
connection_type_t type;
|
||||
@@ -50,7 +49,6 @@ typedef struct http_connection_s http_connection_t;
|
||||
struct httpd_s {
|
||||
logger_t *logger;
|
||||
httpd_callbacks_t callbacks;
|
||||
|
||||
int max_connections;
|
||||
int open_connections;
|
||||
http_connection_t *connections;
|
||||
@@ -192,17 +190,20 @@ httpd_destroy(httpd_t *httpd)
|
||||
{
|
||||
if (httpd) {
|
||||
httpd_stop(httpd);
|
||||
|
||||
free(httpd->connections);
|
||||
free(httpd);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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) {
|
||||
http_request_destroy(connection->request);
|
||||
connection->request = NULL;
|
||||
@@ -214,10 +215,12 @@ httpd_remove_connection(httpd_t *httpd, http_connection_t *connection)
|
||||
connection->user_data = NULL;
|
||||
}
|
||||
if (socket_fd) {
|
||||
shutdown(socket_fd, SHUT_WR);
|
||||
int ret = closesocket(socket_fd);
|
||||
if (!sock_err) {
|
||||
shutdown(socket_fd, SHUT_WR);
|
||||
}
|
||||
int ret = CLOSESOCKET(socket_fd);
|
||||
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 {
|
||||
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);
|
||||
if (ret == -1) {
|
||||
shutdown(fd, SHUT_RDWR);
|
||||
closesocket(fd);
|
||||
CLOSESOCKET(fd);
|
||||
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);
|
||||
if (ret == -1) {
|
||||
shutdown(fd, SHUT_RDWR);
|
||||
closesocket(fd);
|
||||
CLOSESOCKET(fd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -321,7 +324,7 @@ httpd_remove_known_connections(httpd_t *httpd) {
|
||||
if (!connection->connected || connection->type == CONNECTION_TYPE_UNKNOWN) {
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
httpd_remove_connection(httpd, connection);
|
||||
httpd_remove_connection(httpd, connection, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,18 +481,16 @@ httpd_thread(void *arg)
|
||||
if (!connection->socket_fd) {
|
||||
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) {
|
||||
logger_log(httpd->logger, LOGGER_DEBUG, "client closed connection on socket %d",
|
||||
connection->socket_fd);
|
||||
break;
|
||||
} else if (ret == -1) {
|
||||
if (errno == EAGAIN) {
|
||||
if (errno == SOCKET_ERRORNAME(EAGAIN) || errno == SOCKET_ERRORNAME(EWOULDBLOCK) || errno == SOCKET_ERRORNAME(EINTR)) {
|
||||
continue;
|
||||
} else {
|
||||
int sock_err = 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));
|
||||
httpd_remove_connection(httpd, connection, SOCKET_GET_ERROR());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -506,10 +507,17 @@ httpd_thread(void *arg)
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
httpd_remove_connection(httpd, connection);
|
||||
httpd_remove_connection(httpd, connection, 0);
|
||||
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 {
|
||||
/* connection was recently removed */
|
||||
@@ -526,7 +534,7 @@ httpd_thread(void *arg)
|
||||
" on socket %d:\n%s\n", connection->socket_fd, buffer);
|
||||
}
|
||||
if (ret == 0) {
|
||||
httpd_remove_connection(httpd, connection);
|
||||
httpd_remove_connection(httpd, connection, 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -540,7 +548,7 @@ httpd_thread(void *arg)
|
||||
http_request_get_error_description(connection->request),
|
||||
data);
|
||||
free (data);
|
||||
httpd_remove_connection(httpd, connection);
|
||||
httpd_remove_connection(httpd, connection, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -581,7 +589,7 @@ httpd_thread(void *arg)
|
||||
|
||||
if (http_response_get_disconnect(response)) {
|
||||
logger_log(httpd->logger, LOGGER_INFO, "Disconnecting on software request");
|
||||
httpd_remove_connection(httpd, connection);
|
||||
httpd_remove_connection(httpd, connection, 0);
|
||||
}
|
||||
} else {
|
||||
logger_log(httpd->logger, LOGGER_WARNING, "httpd didn't get response");
|
||||
@@ -601,18 +609,18 @@ httpd_thread(void *arg)
|
||||
continue;
|
||||
}
|
||||
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 */
|
||||
if (httpd->server_fd4 != -1) {
|
||||
shutdown(httpd->server_fd4, SHUT_RDWR);
|
||||
closesocket(httpd->server_fd4);
|
||||
CLOSESOCKET(httpd->server_fd4);
|
||||
httpd->server_fd4 = -1;
|
||||
}
|
||||
if (httpd->server_fd6 != -1) {
|
||||
shutdown(httpd->server_fd6, SHUT_RDWR);
|
||||
closesocket(httpd->server_fd6);
|
||||
CLOSESOCKET(httpd->server_fd6);
|
||||
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) {
|
||||
logger_log(httpd->logger, LOGGER_ERR, "Error listening to IPv4 socket");
|
||||
closesocket(httpd->server_fd4);
|
||||
closesocket(httpd->server_fd6);
|
||||
CLOSESOCKET(httpd->server_fd4);
|
||||
CLOSESOCKET(httpd->server_fd6);
|
||||
MUTEX_UNLOCK(httpd->run_mutex);
|
||||
return -2;
|
||||
}
|
||||
if (httpd->server_fd6 != -1 && listen(httpd->server_fd6, backlog) == -1) {
|
||||
logger_log(httpd->logger, LOGGER_ERR, "Error listening to IPv6 socket");
|
||||
closesocket(httpd->server_fd4);
|
||||
closesocket(httpd->server_fd6);
|
||||
CLOSESOCKET(httpd->server_fd4);
|
||||
CLOSESOCKET(httpd->server_fd6);
|
||||
MUTEX_UNLOCK(httpd->run_mutex);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ netutils_init_socket(unsigned short *port, int use_ipv6, int use_udp)
|
||||
cleanup:
|
||||
ret = SOCKET_GET_ERROR();
|
||||
if (server_fd != -1) {
|
||||
closesocket(server_fd);
|
||||
CLOSESOCKET(server_fd);
|
||||
}
|
||||
SOCKET_SET_ERROR(ret);
|
||||
return -1;
|
||||
|
||||
@@ -244,7 +244,7 @@ raop_ntp_init_socket(raop_ntp_t *raop_ntp, int use_ipv6)
|
||||
return 0;
|
||||
|
||||
sockets_cleanup:
|
||||
if (tsock != -1) closesocket(tsock);
|
||||
if (tsock != -1) CLOSESOCKET(tsock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -252,13 +252,11 @@ static void
|
||||
raop_ntp_flush_socket(int fd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#define IOCTL ioctlsocket
|
||||
u_long bytes_available = 0;
|
||||
#else
|
||||
#define IOCTL ioctl
|
||||
int bytes_available = 0;
|
||||
#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.
|
||||
// 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);
|
||||
|
||||
if (raop_ntp->tsock != -1) {
|
||||
closesocket(raop_ntp->tsock);
|
||||
CLOSESOCKET(raop_ntp->tsock);
|
||||
raop_ntp->tsock = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -270,8 +270,8 @@ raop_rtp_init_sockets(raop_rtp_t *raop_rtp, int use_ipv6)
|
||||
return 0;
|
||||
|
||||
sockets_cleanup:
|
||||
if (csock != -1) closesocket(csock);
|
||||
if (dsock != -1) closesocket(dsock);
|
||||
if (csock != -1) CLOSESOCKET(csock);
|
||||
if (dsock != -1) CLOSESOCKET(dsock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -832,11 +832,11 @@ raop_rtp_stop(raop_rtp_t *raop_rtp)
|
||||
THREAD_JOIN(raop_rtp->thread);
|
||||
|
||||
if (raop_rtp->csock != -1) {
|
||||
closesocket(raop_rtp->csock);
|
||||
CLOSESOCKET(raop_rtp->csock);
|
||||
raop_rtp->csock = -1;
|
||||
}
|
||||
if (raop_rtp->dsock != -1) {
|
||||
closesocket(raop_rtp->dsock);
|
||||
CLOSESOCKET(raop_rtp->dsock);
|
||||
raop_rtp->dsock = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -840,7 +840,7 @@ raop_rtp_mirror_thread(void *arg)
|
||||
}
|
||||
/* Close the stream file descriptor */
|
||||
if (stream_fd != -1) {
|
||||
closesocket(stream_fd);
|
||||
CLOSESOCKET(stream_fd);
|
||||
}
|
||||
|
||||
// Ensure running reflects the actual state
|
||||
@@ -854,7 +854,7 @@ raop_rtp_mirror_thread(void *arg)
|
||||
}
|
||||
|
||||
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->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;
|
||||
|
||||
sockets_cleanup:
|
||||
if (dsock != -1) closesocket(dsock);
|
||||
if (dsock != -1) CLOSESOCKET(dsock);
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,11 +38,12 @@ typedef int socklen_t;
|
||||
|
||||
#define WSAEAGAIN WSAEWOULDBLOCK
|
||||
#define WSAENOMEM WSA_NOT_ENOUGH_MEMORY
|
||||
|
||||
#define CLOSESOCKET closesocket
|
||||
#define IOCTLSOCKET ioctlsocket
|
||||
#else
|
||||
|
||||
#define closesocket close
|
||||
#define ioctlsocket ioctl
|
||||
#define CLOSESOCKET close
|
||||
#define IOCTLSOCKET ioctl
|
||||
|
||||
#define SOCKET_GET_ERROR() (errno)
|
||||
#define SOCKET_SET_ERROR(value) (errno = (value))
|
||||
|
||||
Reference in New Issue
Block a user