Disconnect clients upon errors
This commit is contained in:
parent
56681c5b2b
commit
e73edbf782
|
@ -118,6 +118,7 @@ static int _tcp_error(char const * message);
|
||||||
|
|
||||||
/* servers */
|
/* servers */
|
||||||
static int _tcp_server_add_client(TCP * tcp, TCPSocket * client);
|
static int _tcp_server_add_client(TCP * tcp, TCPSocket * client);
|
||||||
|
static int _tcp_server_remove_client(TCP * tcp, TCPSocket * client);
|
||||||
|
|
||||||
/* sockets */
|
/* sockets */
|
||||||
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, int flags,
|
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, int flags,
|
||||||
|
@ -462,6 +463,25 @@ static int _tcp_server_add_client(TCP * tcp, TCPSocket * client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tcp_server_remove_client */
|
||||||
|
static int _tcp_server_remove_client(TCP * tcp, TCPSocket * client)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for(i = 0; i < tcp->u.server.clients_cnt; i++)
|
||||||
|
if(tcp->u.server.clients[i] == client)
|
||||||
|
break;
|
||||||
|
if(i == tcp->u.server.clients_cnt)
|
||||||
|
return -1;
|
||||||
|
tcp->u.server.clients[i] = NULL;
|
||||||
|
_tcp_socket_delete(client);
|
||||||
|
for(i = tcp->u.server.clients_cnt;
|
||||||
|
i > 0 && tcp->u.server.clients[i - 1] == NULL;)
|
||||||
|
tcp->u.server.clients_cnt = --i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* sockets */
|
/* sockets */
|
||||||
/* tcp_socket_init */
|
/* tcp_socket_init */
|
||||||
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, int flags,
|
static int _tcp_socket_init(TCPSocket * tcpsocket, int domain, int flags,
|
||||||
|
@ -709,7 +729,8 @@ static int _tcp_callback_connect(int fd, TCP * tcp)
|
||||||
|
|
||||||
|
|
||||||
/* tcp_socket_callback_read */
|
/* tcp_socket_callback_read */
|
||||||
static AppMessage * _socket_callback_message(TCPSocket * tcpsocket);
|
static int _socket_callback_message(TCPSocket * tcpsocket,
|
||||||
|
AppMessage ** message);
|
||||||
static void _socket_callback_read_client(TCPSocket * tcpsocket,
|
static void _socket_callback_read_client(TCPSocket * tcpsocket,
|
||||||
AppMessage * message);
|
AppMessage * message);
|
||||||
static void _socket_callback_read_server(TCPSocket * tcpsocket,
|
static void _socket_callback_read_server(TCPSocket * tcpsocket,
|
||||||
|
@ -719,6 +740,7 @@ static int _socket_callback_recv(TCPSocket * tcpsocket);
|
||||||
static int _tcp_socket_callback_read(int fd, TCPSocket * tcpsocket)
|
static int _tcp_socket_callback_read(int fd, TCPSocket * tcpsocket)
|
||||||
{
|
{
|
||||||
AppMessage * message;
|
AppMessage * message;
|
||||||
|
int res;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, fd);
|
fprintf(stderr, "DEBUG: %s(%d)\n", __func__, fd);
|
||||||
|
@ -728,7 +750,7 @@ static int _tcp_socket_callback_read(int fd, TCPSocket * tcpsocket)
|
||||||
return -1;
|
return -1;
|
||||||
if(_socket_callback_recv(tcpsocket) != 0)
|
if(_socket_callback_recv(tcpsocket) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
while((message = _socket_callback_message(tcpsocket)) != NULL)
|
while((res = _socket_callback_message(tcpsocket, &message)) > 0)
|
||||||
{
|
{
|
||||||
switch(tcpsocket->tcp->mode)
|
switch(tcpsocket->tcp->mode)
|
||||||
{
|
{
|
||||||
|
@ -743,32 +765,54 @@ static int _tcp_socket_callback_read(int fd, TCPSocket * tcpsocket)
|
||||||
}
|
}
|
||||||
appmessage_delete(message);
|
appmessage_delete(message);
|
||||||
}
|
}
|
||||||
|
if(res < 0)
|
||||||
|
{
|
||||||
|
_tcp_server_remove_client(tcpsocket->tcp, tcpsocket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AppMessage * _socket_callback_message(TCPSocket * tcpsocket)
|
static int _socket_callback_message(TCPSocket * tcpsocket,
|
||||||
|
AppMessage ** message)
|
||||||
{
|
{
|
||||||
AppMessage * message = NULL;
|
int ret = 0;
|
||||||
size_t size;
|
size_t size;
|
||||||
Variable * variable;
|
Variable * variable;
|
||||||
Buffer * buffer;
|
Buffer * buffer;
|
||||||
|
uint32_t u32;
|
||||||
|
|
||||||
size = tcpsocket->bufin_cnt;
|
/* XXX assumes the serialized size is sizeof(u32) */
|
||||||
|
if((size = tcpsocket->bufin_cnt) < sizeof(u32))
|
||||||
|
return 0;
|
||||||
|
/* obtain the message size */
|
||||||
|
if((variable = variable_new_deserialize_type(VT_UINT32, &size,
|
||||||
|
tcpsocket->bufin)) == NULL)
|
||||||
|
return -1;
|
||||||
|
variable_get_as(variable, VT_UINT32, &u32);
|
||||||
|
variable_delete(variable);
|
||||||
|
/* verify the message size */
|
||||||
|
if(u32 > APPMESSAGE_MAX_SIZE)
|
||||||
|
return -error_set_code(E2BIG, "Message too big (%#x)", u32);
|
||||||
|
/* XXX assumes the serialized size is u32 */
|
||||||
|
if(u32 > tcpsocket->bufin_cnt)
|
||||||
|
return 0;
|
||||||
/* deserialize the data as a buffer (containing a message) */
|
/* deserialize the data as a buffer (containing a message) */
|
||||||
|
size = tcpsocket->bufin_cnt;
|
||||||
if((variable = variable_new_deserialize_type(VT_BUFFER, &size,
|
if((variable = variable_new_deserialize_type(VT_BUFFER, &size,
|
||||||
tcpsocket->bufin)) == NULL)
|
tcpsocket->bufin)) == NULL)
|
||||||
/* XXX assumes not enough data was available */
|
return -1;
|
||||||
return NULL;
|
|
||||||
tcpsocket->bufin_cnt -= size;
|
tcpsocket->bufin_cnt -= size;
|
||||||
memmove(tcpsocket->bufin, &tcpsocket->bufin[size],
|
memmove(tcpsocket->bufin, &tcpsocket->bufin[size],
|
||||||
tcpsocket->bufin_cnt);
|
tcpsocket->bufin_cnt);
|
||||||
if((variable_get_as(variable, VT_BUFFER, &buffer)) == 0)
|
if((variable_get_as(variable, VT_BUFFER, &buffer)) == 0)
|
||||||
{
|
{
|
||||||
message = appmessage_new_deserialize(buffer);
|
*message = appmessage_new_deserialize(buffer);
|
||||||
buffer_delete(buffer);
|
buffer_delete(buffer);
|
||||||
|
ret = (*message != NULL) ? 1 : -1;
|
||||||
}
|
}
|
||||||
variable_delete(variable);
|
variable_delete(variable);
|
||||||
return message;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _socket_callback_read_client(TCPSocket * tcpsocket,
|
static void _socket_callback_read_client(TCPSocket * tcpsocket,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user