summaryrefslogtreecommitdiffhomepage
path: root/src/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/loop.c')
-rw-r--r--src/loop.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/loop.c b/src/loop.c
new file mode 100644
index 0000000..d696760
--- /dev/null
+++ b/src/loop.c
@@ -0,0 +1,81 @@
+#include <pthread.h>
+#include <time.h>
+#include "loop.h"
+#include "conf.h"
+#include "main.h"
+#include "sblist.h"
+#include "sock.h"
+
+struct loop_record {
+ union sockaddr_union addr;
+ time_t tstamp;
+};
+
+static sblist *loop_records;
+static pthread_mutex_t loop_records_lock = PTHREAD_MUTEX_INITIALIZER;
+
+void loop_records_init(void) {
+ loop_records = sblist_new(sizeof (struct loop_record), 32);
+}
+
+void loop_records_destroy(void) {
+ sblist_free(loop_records);
+ loop_records = 0;
+}
+
+#if 0
+static void su_to_str(union sockaddr_union *addr, char *buf) {
+ int af = addr->v4.sin_family;
+ unsigned port = ntohs(af == AF_INET ? addr->v4.sin_port : addr->v6.sin6_port);
+ char portb[32];
+ sprintf(portb, ":%u", port);
+ getpeer_information (addr, buf, 256);
+ strcat(buf, portb);
+}
+#endif
+
+void loop_records_add(union sockaddr_union *addr) {
+ time_t now =time(0);
+ struct loop_record rec;
+ pthread_mutex_lock(&loop_records_lock);
+ rec.tstamp = now;
+ rec.addr = *addr;
+ sblist_add(loop_records, &rec);
+ pthread_mutex_unlock(&loop_records_lock);
+}
+
+#define TIMEOUT_SECS 15
+
+int connection_loops (union sockaddr_union *addr) {
+ int ret = 0, af, our_af = addr->v4.sin_family;
+ void *ipdata, *our_ipdata = our_af == AF_INET ? (void*)&addr->v4.sin_addr.s_addr : (void*)&addr->v6.sin6_addr.s6_addr;
+ size_t i, cmp_len = our_af == AF_INET ? sizeof(addr->v4.sin_addr.s_addr) : sizeof(addr->v6.sin6_addr.s6_addr);
+ unsigned port, our_port = ntohs(our_af == AF_INET ? addr->v4.sin_port : addr->v6.sin6_port);
+ time_t now = time(0);
+
+ pthread_mutex_lock(&loop_records_lock);
+ for (i = 0; i < sblist_getsize(loop_records); ) {
+ struct loop_record *rec = sblist_get(loop_records, i);
+
+ if (rec->tstamp + TIMEOUT_SECS < now) {
+ sblist_delete(loop_records, i);
+ continue;
+ }
+
+ if (!ret) {
+ af = rec->addr.v4.sin_family;
+ if (af != our_af) goto next;
+ port = ntohs(af == AF_INET ? rec->addr.v4.sin_port : rec->addr.v6.sin6_port);
+ if (port != our_port) goto next;
+ ipdata = af == AF_INET ? (void*)&rec->addr.v4.sin_addr.s_addr : (void*)&rec->addr.v6.sin6_addr.s6_addr;
+ if (!memcmp(ipdata, our_ipdata, cmp_len)) {
+ ret = 1;
+ }
+ }
+next:
+ i++;
+ }
+ pthread_mutex_unlock(&loop_records_lock);
+ return ret;
+}
+