mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Listen for and accept/close client connections in router code.
This commit is contained in:
parent
8928ae23cc
commit
6d6ac5f2c3
@ -8,6 +8,8 @@ ntohl
|
||||
htons
|
||||
ntohs
|
||||
select
|
||||
listen
|
||||
accept
|
||||
WSACreateEvent
|
||||
WSAEventSelect
|
||||
WSACloseEvent
|
||||
|
96
src/router.c
96
src/router.c
@ -38,7 +38,8 @@ struct router_vars *router_init(BOOL global) {
|
||||
router->running = TRUE;
|
||||
router->interfaces = NULL;
|
||||
router->udp_sock = -1;
|
||||
router->listner = -1;
|
||||
router->listener = -1;
|
||||
router->client_count = 0;
|
||||
router->wsa_event = WSA_INVALID_EVENT;
|
||||
router->crit_sec_init = FALSE;
|
||||
router->addrs = NULL;
|
||||
@ -104,7 +105,37 @@ struct router_vars *router_init(BOOL global) {
|
||||
}
|
||||
|
||||
if(global) {
|
||||
/* TODO: Global (service) router support */
|
||||
if((router->listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
|
||||
log_printf("Failed to create TCP socket: %s", w32_error(WSAGetLastError()));
|
||||
|
||||
router_destroy(router);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: Use different port number for control socket? */
|
||||
|
||||
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
|
||||
if(bind(router->listener, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
||||
log_printf("Failed to bind TCP socket: %s", w32_error(WSAGetLastError()));
|
||||
|
||||
router_destroy(router);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(listen(router->listener, 8) == -1) {
|
||||
log_printf("Failed to listen for connections: %s", w32_error(WSAGetLastError()));
|
||||
|
||||
router_destroy(router);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(WSAEventSelect(router->listener, router->wsa_event, FD_ACCEPT) == -1) {
|
||||
log_printf("WSAEventSelect error: %s", w32_error(WSAGetLastError()));
|
||||
|
||||
router_destroy(router);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return router;
|
||||
@ -113,6 +144,7 @@ struct router_vars *router_init(BOOL global) {
|
||||
/* Release all resources allocated by a router and free it */
|
||||
void router_destroy(struct router_vars *router) {
|
||||
struct router_addr *addr = router->addrs;
|
||||
int i;
|
||||
|
||||
while(addr) {
|
||||
struct router_addr *del = addr;
|
||||
@ -121,6 +153,14 @@ void router_destroy(struct router_vars *router) {
|
||||
free(del);
|
||||
}
|
||||
|
||||
for(i = 0; i < router->client_count; i++) {
|
||||
closesocket(router->clients[i].sock);
|
||||
}
|
||||
|
||||
if(router->listener != -1) {
|
||||
closesocket(router->listener);
|
||||
}
|
||||
|
||||
free(router->recvbuf);
|
||||
|
||||
if(router->udp_sock != -1) {
|
||||
@ -159,6 +199,58 @@ DWORD router_main(void *arg) {
|
||||
|
||||
LeaveCriticalSection(&(router->crit_sec));
|
||||
|
||||
if(router->listener != -1) {
|
||||
int newfd = accept(router->listener, NULL, NULL);
|
||||
if(newfd != -1) {
|
||||
if(router->client_count == MAX_ROUTER_CLIENTS) {
|
||||
log_printf("Too many clients, dropping new connection!");
|
||||
goto DROP_NEWFD;
|
||||
}
|
||||
|
||||
if(WSAEventSelect(newfd, router->wsa_event, FD_READ | FD_CLOSE) == -1) {
|
||||
log_printf("WSAEventSelect error: %s", w32_error(WSAGetLastError()));
|
||||
goto DROP_NEWFD;
|
||||
}
|
||||
|
||||
router->clients[router->client_count].sock = newfd;
|
||||
router->clients[router->client_count++].recvbuf_len = 0;
|
||||
|
||||
if(0) {
|
||||
DROP_NEWFD:
|
||||
closesocket(newfd);
|
||||
}
|
||||
}else if(WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
log_printf("Failed to accept client connection: %s", w32_error(WSAGetLastError()));
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i = 0; i < router->client_count; i++) {
|
||||
char *bstart = ((char*)&(router->clients[i].recvbuf)) + router->clients[i].recvbuf_len;
|
||||
int len = sizeof(struct router_call) - router->clients[i].recvbuf_len;
|
||||
|
||||
if((len = recv(router->clients[i].sock, bstart, len, 0) == -1) || len == 0) {
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAECONNRESET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(len == -1) {
|
||||
log_printf("Error reading from client socket: %s", w32_error(WSAGetLastError()));
|
||||
}
|
||||
|
||||
closesocket(router->clients[i].sock);
|
||||
memcpy(&(router->clients[i]), &(router->clients[--router->client_count]), sizeof(struct router_client));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if((router->clients[i].recvbuf_len += len) == sizeof(struct router_call)) {
|
||||
/* TODO: Handle call */
|
||||
|
||||
router->clients[i].recvbuf_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
int addrlen = sizeof(addr);
|
||||
|
||||
|
36
src/router.h
36
src/router.h
@ -23,6 +23,30 @@
|
||||
#include <wsipx.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_ROUTER_CLIENTS 128
|
||||
|
||||
struct router_call {
|
||||
enum {
|
||||
rc_bind,
|
||||
rc_unbind,
|
||||
rc_port,
|
||||
rc_filter,
|
||||
rc_reuse
|
||||
} call;
|
||||
|
||||
SOCKET sock;
|
||||
|
||||
struct sockaddr_ipx arg_addr;
|
||||
int arg_int;
|
||||
};
|
||||
|
||||
struct router_ret {
|
||||
int err_code; /* ERROR_SUCCESS on success */
|
||||
|
||||
struct sockaddr_ipx ret_addr;
|
||||
int ret_int;
|
||||
};
|
||||
|
||||
/* Represents a bound IPX address */
|
||||
struct router_addr {
|
||||
struct sockaddr_ipx addr;
|
||||
@ -36,13 +60,23 @@ struct router_addr {
|
||||
struct router_addr *next;
|
||||
};
|
||||
|
||||
struct router_client {
|
||||
SOCKET sock;
|
||||
|
||||
struct router_call recvbuf;
|
||||
int recvbuf_len;
|
||||
};
|
||||
|
||||
struct router_vars {
|
||||
BOOL running;
|
||||
|
||||
struct ipx_interface *interfaces;
|
||||
|
||||
SOCKET udp_sock;
|
||||
SOCKET listner;
|
||||
SOCKET listener;
|
||||
|
||||
struct router_client clients[MAX_ROUTER_CLIENTS];
|
||||
int client_count;
|
||||
|
||||
WSAEVENT wsa_event;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user