mirror of
https://codeberg.org/scip/udpxd.git
synced 2025-12-16 19:40:58 +01:00
v4 works again
This commit is contained in:
8
client.c
8
client.c
@@ -60,18 +60,18 @@ client_t *client_new(int fd, host_t *src, host_t *dst) {
|
||||
void client_close(client_t *client) {
|
||||
client_del(client);
|
||||
close(client->socket);
|
||||
free(client->src);
|
||||
free(client->dst);
|
||||
host_clean(client->src);
|
||||
host_clean(client->dst);
|
||||
free(client);
|
||||
}
|
||||
|
||||
void client_clean() {
|
||||
void client_clean(int asap) {
|
||||
uint32_t now = (long)time(0);
|
||||
uint32_t diff;
|
||||
client_t *current;
|
||||
client_iter(clients, current) {
|
||||
diff = now - current->lastseen;
|
||||
if(diff >= MAXAGE) {
|
||||
if(diff >= MAXAGE || asap) {
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "closing socket %s:%d for client %s:%d (aged out after %d seconds)\n",
|
||||
current->src->ip, current->src->port, current->dst->ip, current->dst->port, MAXAGE);
|
||||
|
||||
3
client.h
3
client.h
@@ -48,7 +48,6 @@ struct _client_t {
|
||||
host_t *src; /* client src (ip+port) from incoming socket */
|
||||
host_t *dst; /* client dst (ip+port) to outgoing socket */
|
||||
uint64_t lastseen; /* when did we recv last time from it */
|
||||
size_t size; /* sockaddr size */
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
typedef struct _client_t client_t;
|
||||
@@ -77,7 +76,7 @@ void client_del(client_t *client);
|
||||
void client_add(client_t *client);
|
||||
void client_seen(client_t *client);
|
||||
void client_close(client_t *client);
|
||||
void client_clean();
|
||||
void client_clean(int asap);
|
||||
|
||||
client_t *client_find_fd(int fd);
|
||||
client_t *client_find_src(host_t *src);
|
||||
|
||||
19
host.c
19
host.c
@@ -49,6 +49,8 @@ host_t *get_host(char *ip, int port, struct sockaddr_in *v4, struct sockaddr_in6
|
||||
host->is_v6 = 1;
|
||||
host->sock = (struct sockaddr*)tmp;
|
||||
host->size = sizeof(struct sockaddr_in6);
|
||||
host->ip = malloc(INET6_ADDRSTRLEN+1);
|
||||
memcpy(host->ip, ip, INET6_ADDRSTRLEN);
|
||||
}
|
||||
else {
|
||||
struct sockaddr_in *tmp = malloc(sizeof(struct sockaddr_in));
|
||||
@@ -58,6 +60,8 @@ host_t *get_host(char *ip, int port, struct sockaddr_in *v4, struct sockaddr_in6
|
||||
tmp->sin_port = htons( port );
|
||||
host->sock = (struct sockaddr*)tmp;
|
||||
host->size = sizeof(struct sockaddr_in);
|
||||
host->ip = malloc(INET_ADDRSTRLEN+1);
|
||||
memcpy(host->ip, ip, INET_ADDRSTRLEN);
|
||||
}
|
||||
}
|
||||
else if(v4 != NULL) {
|
||||
@@ -68,6 +72,7 @@ host_t *get_host(char *ip, int port, struct sockaddr_in *v4, struct sockaddr_in6
|
||||
host->port = ntohs(tmp->sin_port);
|
||||
host->sock = (struct sockaddr*)tmp;
|
||||
host->size = sizeof(struct sockaddr_in);
|
||||
//fprintf(stderr, "%s sock: %p\n", host->ip, tmp);
|
||||
}
|
||||
else if(v6 != NULL) {
|
||||
struct sockaddr_in6 *tmp = malloc(sizeof(struct sockaddr_in6));
|
||||
@@ -130,3 +135,17 @@ unsigned get_v6_scope(const char *ip){
|
||||
int is_linklocal(struct in6_addr *a) {
|
||||
return ((a->s6_addr[0] == 0xfe) && ((a->s6_addr[1] & 0xc0) == 0x80));
|
||||
}
|
||||
|
||||
void host_dump(host_t *host) {
|
||||
fprintf(stderr, "host - ip: %s\n", host->ip);
|
||||
fprintf(stderr, " port: %d\n", host->port);
|
||||
fprintf(stderr, " isv6: %d\n", host->is_v6);
|
||||
fprintf(stderr, " size: %ld\n", host->size);
|
||||
fprintf(stderr, " src: %p\n", host->sock);
|
||||
}
|
||||
|
||||
void host_clean(host_t *host) {
|
||||
free(host->sock);
|
||||
free(host->ip);
|
||||
free(host);
|
||||
}
|
||||
|
||||
2
host.h
2
host.h
@@ -50,5 +50,7 @@ unsigned get_v6_scope(const char *ip);
|
||||
int is_linklocal(struct in6_addr *a);
|
||||
host_t *get_host(char *ip, int port, struct sockaddr_in *v4, struct sockaddr_in6 *v6);
|
||||
char *is_v6(char *ip);
|
||||
void host_dump(host_t *host);
|
||||
void host_clean(host_t *host);
|
||||
|
||||
#endif
|
||||
|
||||
54
net.c
54
net.c
@@ -102,6 +102,7 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstp
|
||||
bind_h = get_host("0.0.0.0", 0, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
int listen = bindsocket(listen_h);
|
||||
|
||||
if(listen == -1)
|
||||
@@ -118,13 +119,14 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstp
|
||||
|
||||
main_loop(listen, listen_h, bind_h, dst_h);
|
||||
|
||||
host_clean(bind_h);
|
||||
host_clean(listen_h);
|
||||
host_clean(dst_h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handle new or known incoming requests
|
||||
FIXME: check client handling:
|
||||
http://long.ccaba.upc.es/long/045Guidelines/eva/ipv6.html#daytimeServer6
|
||||
*/
|
||||
/* handle new or known incoming requests */
|
||||
void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h) {
|
||||
int len;
|
||||
unsigned char buffer[MAX_BUFFER_SIZE];
|
||||
@@ -144,6 +146,8 @@ void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h)
|
||||
else
|
||||
src_h = get_host(NULL, 0, (struct sockaddr_in *)src, NULL);
|
||||
|
||||
free(src);
|
||||
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "New incomming request from %s:%d with %d bytes\n",
|
||||
src_h->ip, src_h->port, len);
|
||||
@@ -155,7 +159,7 @@ void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h)
|
||||
if(client != NULL) {
|
||||
/* yes, we know it, send req out via existing bind socket */
|
||||
if(VERBOSE) {
|
||||
fprintf(stderr, "Client %s:%d is known, forwarding data to %s:%d\n",
|
||||
fprintf(stderr, "Client %s:%d is known, forwarding data to %s:%d ",
|
||||
src_h->ip, src_h->port, dst_h->ip, dst_h->port);
|
||||
|
||||
}
|
||||
@@ -189,12 +193,14 @@ void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h)
|
||||
struct sockaddr_in6 *ret = malloc(size);
|
||||
getsockname(output, (struct sockaddr*)ret, (socklen_t *)&size);
|
||||
ret_h = get_host(NULL, 0, NULL, ret);
|
||||
free(ret);
|
||||
client = client_new(output, src_h, ret_h);
|
||||
}
|
||||
else {
|
||||
struct sockaddr_in *ret = malloc(size);
|
||||
getsockname(output, (struct sockaddr*)ret, (socklen_t *)&size);
|
||||
ret_h = get_host(NULL, 0, ret, NULL);
|
||||
free(ret);
|
||||
client = client_new(output, src_h, ret_h);
|
||||
}
|
||||
|
||||
@@ -226,26 +232,44 @@ void handle_outside(int inside, int outside, host_t *outside_h) {
|
||||
src = malloc(size);
|
||||
|
||||
len = recvfrom( outside, buffer, sizeof( buffer ), 0, (struct sockaddr*)src, (socklen_t *)&size );
|
||||
free(src);
|
||||
|
||||
if(len > 0) {
|
||||
/* do we know it? */
|
||||
client = client_find_fd(outside);
|
||||
if(client != NULL) {
|
||||
/* yes, we know it */
|
||||
if(sendto(inside, buffer, len, 0, (struct sockaddr*)client->src, client->size) < 0) {
|
||||
/* FIXME: check src vs. client->src ? */
|
||||
if(sendto(inside, buffer, len, 0,
|
||||
(struct sockaddr*)client->src->sock, client->src->size) < 0) {
|
||||
perror("unable to send back to client"); /* FIXME: add src+port */
|
||||
client_close(client);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "weird, no matching client found!\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "weird, recvfrom returned 0 bytes!\n");
|
||||
}
|
||||
}
|
||||
|
||||
jmp_buf JumpBuffer;
|
||||
|
||||
/* runs forever, handles incoming requests on the inside and answers on the outside */
|
||||
int main_loop(int listensocket, host_t *listen_h, host_t *bind_h, host_t *dst_h) {
|
||||
int max, sender;
|
||||
fd_set fds;
|
||||
|
||||
signal(SIGINT, int_handler);
|
||||
signal(SIGTERM, int_handler);
|
||||
|
||||
for(;;) {
|
||||
if (setjmp(JumpBuffer) == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
max = fill_set(&fds);
|
||||
|
||||
@@ -267,6 +291,22 @@ int main_loop(int listensocket, host_t *listen_h, host_t *bind_h, host_t *dst_h)
|
||||
}
|
||||
|
||||
/* close old outputs, if any */
|
||||
client_clean();
|
||||
client_clean(0);
|
||||
}
|
||||
|
||||
/* we came here via signal handler,
|
||||
clean up */
|
||||
client_t *current = NULL;
|
||||
client_iter(clients, current) {
|
||||
close(current->socket);
|
||||
}
|
||||
close(listensocket);
|
||||
client_clean(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void int_handler(int sig) {
|
||||
signal(sig, SIG_IGN);
|
||||
longjmp(JumpBuffer, 1);
|
||||
}
|
||||
|
||||
4
net.h
4
net.h
@@ -28,6 +28,8 @@
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -54,7 +56,7 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstp
|
||||
int fill_set(fd_set *fds);
|
||||
int get_sender(fd_set *fds);
|
||||
int bindsocket( host_t *sock_h);
|
||||
|
||||
void int_handler(int sig);
|
||||
|
||||
|
||||
#define _IS_LINK_LOCAL(a) do { IN6_IS_ADDR_LINKLOCAL(a); } while(0)
|
||||
|
||||
Reference in New Issue
Block a user