]> git.sesse.net Git - greproxy/commitdiff
Port greproxy to all the new classes and stuff.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 7 Feb 2015 00:46:41 +0000 (01:46 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 7 Feb 2015 00:46:41 +0000 (01:46 +0100)
Makefile
greproxy.cpp

index a0a877434dbb87dc13f851b8c28ec8aa8262041f..aeb7ba9d4f3a80d07ccaa5be0178e03204b0a62f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,18 @@
 CXXFLAGS=-std=gnu++11 -O2 -g
 
-TUNGRE_OBJS=greprotocol.o reorderer.o tungre.o tunprotocol.o
+TUNGRE_OBJS=tungre.o greprotocol.o reorderer.o tunprotocol.o
+GREPROXY_OBJS=greproxy.o greprotocol.o reorderer.o tunprotocol.o
 
+all: tungre greproxy
 tungre: $(TUNGRE_OBJS)
        $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS)
+greproxy: $(GREPROXY_OBJS)
+       $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 %.o: %.cpp
        $(CXX) -MMD -MP $(CPPFLAGS) $(CXXFLAGS) -o $@ -c $<
-DEPS=$(TUNGRE_OBJS:.o=.d)
+DEPS=$(TUNGRE_OBJS:.o=.d) $(GREPROXY_OBJS:.o=.d)
 -include $(DEPS)
 
 clean:
-       $(RM) $(TUNGRE_OBJS) $(DEPS) gretun
+       $(RM) $(TUNGRE_OBJS) $(GREPROXY_OBJS) $(DEPS) gretun greproxy
index af0ba49eedb84150d8457c09204649a6f27de836..fa116b63da7e7175774b584a9751e5c130f3e463 100644 (file)
@@ -9,20 +9,12 @@
 #include <string>
 #include <queue>
 
-using namespace std;
-
-struct gre_header {
-       uint8_t reserved0_hi : 4;
-       uint8_t has_seq : 1;
-       uint8_t has_key : 1;
-       uint8_t unused : 1;
-       uint8_t has_checksum : 1;
-
-       uint8_t version : 3;
-       uint8_t reserved0_lo: 5;
+#include "greprotocol.h"
+#include "protocol.h"
+#include "reorderer.h"
+#include "tunprotocol.h"
 
-       uint16_t protocol_type;
-};
+using namespace std;
 
 in6_addr get_addr(const char *str) {
        in6_addr ret;
@@ -33,170 +25,32 @@ in6_addr get_addr(const char *str) {
        return ret;
 }
 
-struct GREPacket {
-       int seq;
-       string data;
-
-       bool operator> (const GREPacket &other) const {
-               return seq > other.seq;
-       }
-};
-
-class Reorderer {
-public:
-       Reorderer(int sock, const in6_addr &dst);
-       void handle_packet(const char* buf, size_t size, int seq);
-
-private:
-       void send_packet(const string &data);
-
-       int sock;
-       sockaddr_in6 dstaddr;
-       int last_seq;
-
-       priority_queue<GREPacket, vector<GREPacket>, greater<GREPacket>> packet_buffer;
-       map<int, int> ccs;
-};
-
-Reorderer::Reorderer(int sock, const in6_addr &dst)
-       : sock(sock), last_seq(-1)
-{
-       memset(&dstaddr, 0, sizeof(dstaddr));
-       dstaddr.sin6_family = AF_INET6;
-       dstaddr.sin6_addr = dst;
-}
-
-#define PACKET_BUFFER_SIZE 100
-
-void Reorderer::handle_packet(const char* buf, size_t size, int seq)
-{
-       if (packet_buffer.size() >= PACKET_BUFFER_SIZE) {
-               printf("Gave up waiting for packets [%d,%d>\n",
-                       last_seq + 1, packet_buffer.top().seq);
-               last_seq = packet_buffer.top().seq - 1;
-       }
-
-       GREPacket packet;
-       packet.seq = seq;
-       packet.data = string(buf, buf + size);
-       packet_buffer.push(packet);
-
-       bool silence = false;
-       while (!packet_buffer.empty() &&
-              (last_seq == -1 || packet_buffer.top().seq <= last_seq + 1)) {
-               int front_seq = packet_buffer.top().seq;
-               if (front_seq < last_seq + 1) {
-                       printf("Duplicate packet or way out-of-order: seq=%d front_seq=%d\n",
-                               seq, front_seq);
-                       packet_buffer.pop();
-                       continue;
-               }
-               //if (packet_buffer.size() > 1) {
-               //      printf("seq=%d (REORDER %d)\n", front_seq, int(packet_buffer.size()));
-               //} else {
-               //      printf("seq=%d\n", front_seq);
-               //}
-               const string &data = packet_buffer.top().data;
-               send_packet(data);
-               packet_buffer.pop();
-               last_seq = front_seq;
-               if (!silence && !packet_buffer.empty()) {
-                       printf("Reordering with packet buffer size %d: seq=%d new_front_seq=%d\n", int(packet_buffer.size()), front_seq, packet_buffer.top().seq);
-                       silence = true;
-               }
-       }
-}
-
-void Reorderer::send_packet(const string &data)
-{
-       if (data.size() == 1352) {
-               for (int i = 0; i < 7; ++i) {
-                       const char *pkt = &data[i * 188 + 36];
-                       int pid = (ntohl(*(uint32_t *)(pkt)) & 0x1fff00) >> 8;
-                       int has_payload = pkt[3] & 0x10;
-                       int cc = pkt[3] & 0xf;
-                       if (has_payload) {
-                               int last_cc = ccs[pid];
-                               if (cc != ((last_cc + 1) & 0xf)) {
-                                       printf("Pid %d discontinuity (expected %d, got %d)\n", pid, (last_cc + 1) & 0xf, cc);
-                               }
-                               ccs[pid] = cc;
-                       }
-               }
-       }
-       if (sendto(sock, data.data(), data.size(), 0, (sockaddr *)&dstaddr, sizeof(dstaddr)) == -1) {
-               perror("sendto");
-               return;
-       }
-}
-
 int main(int argc, char **argv)
 {
-       int sock = socket(AF_INET6, SOCK_RAW, IPPROTO_GRE);
-       if (sock == -1) {
-               perror("socket");
-               exit(1);
-       }
-
-       sockaddr_in6 my_addr;
-       memset(&my_addr, 0, sizeof(my_addr));
-       my_addr.sin6_family = AF_INET6;
-       my_addr.sin6_addr = get_addr(argv[3]);
-       if (bind(sock, (sockaddr *)&my_addr, sizeof(my_addr)) == -1) {
-               perror("bind");
-               exit(1);
-       }
-
        in6_addr addr_a = get_addr(argv[1]);
        in6_addr addr_b = get_addr(argv[2]);
-       Reorderer dst_a(sock, addr_a);
-       Reorderer dst_b(sock, addr_b);
-
+       in6_addr myaddr = get_addr(argv[3]);
+       GREProtocol gre_a(myaddr, addr_a);
+       GREProtocol gre_b(myaddr, addr_b);
+       Reorderer dst_a(&gre_a);
+       Reorderer dst_b(&gre_b);
+
+       fd_set fds;
+       FD_ZERO(&fds);
        for ( ;; ) {
-               char addrstr[256];
-               struct sockaddr_storage addr;
-               socklen_t addrlen = sizeof(addr);
-               char buf[4096];
-               int ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&addr, &addrlen);
+               FD_SET(gre_a.fd(), &fds);
+               FD_SET(gre_b.fd(), &fds);
+               int ret = select(1024, &fds, NULL, NULL, NULL);
                if (ret == -1) {
-                       perror("recvfrom");
-                       exit(1);
-               }
-               if (addr.ss_family != AF_INET6) {
-                       // ignore
-                       //inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr, addrstr, sizeof(addrstr));
-                       continue;
-               }
-               struct in6_addr *addr6 = &((struct sockaddr_in6 *)&addr)->sin6_addr;
-               if (memcmp(addr6, &addr_a, sizeof(*addr6)) != 0 &&
-                   memcmp(addr6, &addr_b, sizeof(*addr6)) != 0) {
-                       // ignore
+                       perror("select");
                        continue;
                }
-               inet_ntop(AF_INET6, addr6, addrstr, sizeof(addrstr));
-               gre_header* gre = (gre_header *)buf;
-               //printf("GREv%d of %d bytes from %s: %02x %02x %02x %02x\n", gre->version, ret, addrstr,
-               //      buf[0], buf[1], buf[2], buf[3]);
-               //printf("  has_checksum=%d, has_key=%d, has_seq=%d\n", gre->has_checksum, gre->has_key, gre->has_seq);
 
-               char* ptr = buf + sizeof(gre_header);
-               if (gre->has_checksum) {
-                       ptr += 4;
-               }
-               if (gre->has_key) {
-                       ptr += 4;
-               }
-               uint32_t seq;
-               if (gre->has_seq) {
-                       seq = ntohl(*(uint32_t *)ptr);
-               //      printf("  seq=%d\n", seq);
+               if (FD_ISSET(gre_a.fd(), &fds)) {
+                       gre_a.read_packet(&dst_b);
                }
-               if (memcmp(addr6, &addr_a, sizeof(*addr6)) == 0) {
-                       // comes from A, send to B
-                       dst_b.handle_packet(buf, ret, seq);
-               } else {
-                       // comes from B, send to A
-                       dst_a.handle_packet(buf, ret, seq);
+               if (FD_ISSET(gre_b.fd(), &fds)) {
+                       gre_b.read_packet(&dst_a);
                }
        }
 }