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
|
htons
|
||||||
ntohs
|
ntohs
|
||||||
select
|
select
|
||||||
|
listen
|
||||||
|
accept
|
||||||
WSACreateEvent
|
WSACreateEvent
|
||||||
WSAEventSelect
|
WSAEventSelect
|
||||||
WSACloseEvent
|
WSACloseEvent
|
||||||
|
96
src/router.c
96
src/router.c
@ -38,7 +38,8 @@ struct router_vars *router_init(BOOL global) {
|
|||||||
router->running = TRUE;
|
router->running = TRUE;
|
||||||
router->interfaces = NULL;
|
router->interfaces = NULL;
|
||||||
router->udp_sock = -1;
|
router->udp_sock = -1;
|
||||||
router->listner = -1;
|
router->listener = -1;
|
||||||
|
router->client_count = 0;
|
||||||
router->wsa_event = WSA_INVALID_EVENT;
|
router->wsa_event = WSA_INVALID_EVENT;
|
||||||
router->crit_sec_init = FALSE;
|
router->crit_sec_init = FALSE;
|
||||||
router->addrs = NULL;
|
router->addrs = NULL;
|
||||||
@ -104,7 +105,37 @@ struct router_vars *router_init(BOOL global) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(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;
|
return router;
|
||||||
@ -113,6 +144,7 @@ struct router_vars *router_init(BOOL global) {
|
|||||||
/* Release all resources allocated by a router and free it */
|
/* Release all resources allocated by a router and free it */
|
||||||
void router_destroy(struct router_vars *router) {
|
void router_destroy(struct router_vars *router) {
|
||||||
struct router_addr *addr = router->addrs;
|
struct router_addr *addr = router->addrs;
|
||||||
|
int i;
|
||||||
|
|
||||||
while(addr) {
|
while(addr) {
|
||||||
struct router_addr *del = addr;
|
struct router_addr *del = addr;
|
||||||
@ -121,6 +153,14 @@ void router_destroy(struct router_vars *router) {
|
|||||||
free(del);
|
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);
|
free(router->recvbuf);
|
||||||
|
|
||||||
if(router->udp_sock != -1) {
|
if(router->udp_sock != -1) {
|
||||||
@ -159,6 +199,58 @@ DWORD router_main(void *arg) {
|
|||||||
|
|
||||||
LeaveCriticalSection(&(router->crit_sec));
|
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;
|
struct sockaddr_in addr;
|
||||||
int addrlen = sizeof(addr);
|
int addrlen = sizeof(addr);
|
||||||
|
|
||||||
|
36
src/router.h
36
src/router.h
@ -23,6 +23,30 @@
|
|||||||
#include <wsipx.h>
|
#include <wsipx.h>
|
||||||
#include <stdint.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 */
|
/* Represents a bound IPX address */
|
||||||
struct router_addr {
|
struct router_addr {
|
||||||
struct sockaddr_ipx addr;
|
struct sockaddr_ipx addr;
|
||||||
@ -36,13 +60,23 @@ struct router_addr {
|
|||||||
struct router_addr *next;
|
struct router_addr *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct router_client {
|
||||||
|
SOCKET sock;
|
||||||
|
|
||||||
|
struct router_call recvbuf;
|
||||||
|
int recvbuf_len;
|
||||||
|
};
|
||||||
|
|
||||||
struct router_vars {
|
struct router_vars {
|
||||||
BOOL running;
|
BOOL running;
|
||||||
|
|
||||||
struct ipx_interface *interfaces;
|
struct ipx_interface *interfaces;
|
||||||
|
|
||||||
SOCKET udp_sock;
|
SOCKET udp_sock;
|
||||||
SOCKET listner;
|
SOCKET listener;
|
||||||
|
|
||||||
|
struct router_client clients[MAX_ROUTER_CLIENTS];
|
||||||
|
int client_count;
|
||||||
|
|
||||||
WSAEVENT wsa_event;
|
WSAEVENT wsa_event;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user