Changeset 58d961


Ignore:
Timestamp:
08/06/09 21:48:55 (4 years ago)
Author:
Erik Ekman <yarrick@…>
Branches:
master
Children:
e5370a
Parents:
02c06d
git-author:
Erik Ekman <yarrick@…> (08/06/09 21:48:55)
git-committer:
Erik Ekman <erik@…> (02/04/12 20:34:02)
Message:

#36, upstream traffic now sent in raw mode

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/common.h

    rd5acb5 r58d961  
    2222#define RAW_HDR_IDENT_LEN 3 
    2323#define RAW_HDR_CMD 3 
    24 #define RAW_HDR_CMD_LOGIN 0x01 
    25 #define RAW_HDR_CMD_DATA  0x02 
     24#define RAW_HDR_CMD_LOGIN 0x10 
     25#define RAW_HDR_CMD_DATA  0x20 
     26 
     27#define RAW_HDR_CMD_MASK  0xF0 
     28#define RAW_HDR_USR_MASK  0x0F 
     29#define RAW_HDR_GET_CMD(x) ((x)[RAW_HDR_CMD] & RAW_HDR_CMD_MASK) 
     30#define RAW_HDR_GET_USR(x) ((x)[RAW_HDR_CMD] & RAW_HDR_USR_MASK) 
    2631extern const unsigned char raw_header[RAW_HDR_LEN]; 
    2732 
     
    8691}; 
    8792 
     93enum connection { 
     94        CONN_RAW_UDP, 
     95        CONN_DNS_NULL, 
     96        CONN_MAX 
     97}; 
     98 
    8899void check_superuser(void (*usage_fn)(void)); 
    89100int open_dns(int, in_addr_t); 
  • src/iodine.c

    r02c06d r58d961  
    6161static void send_ping(int fd); 
    6262static void send_chunk(int fd); 
     63static void send_raw_data(int fd); 
    6364static int build_hostname(char *buf, size_t buflen,  
    6465        const char *data, const size_t datalen,  
     
    9596static struct encoder *dataenc; 
    9697 
     98/* My connection mode */ 
     99static enum connection conn; 
     100 
    97101#if !defined(BSD) && !defined(__GLIBC__) 
    98102static char *__progname; 
     
    121125 
    122126static void 
    123 send_raw(int fd, char *buf, int buflen, int cmd) 
     127send_raw(int fd, char *buf, int buflen, int user, int cmd) 
    124128{ 
    125129        char packet[4096]; 
     
    132136 
    133137        len += RAW_HDR_LEN; 
    134         packet[RAW_HDR_CMD] = cmd; 
     138        packet[RAW_HDR_CMD] = cmd | (user & 0x0F); 
    135139 
    136140        sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv)); 
     
    264268        outpkt.fragment = 0; 
    265269 
    266         send_chunk(dns_fd); 
     270        if (conn == CONN_DNS_NULL) { 
     271                send_chunk(dns_fd); 
     272        } else { 
     273                send_raw_data(dns_fd); 
     274        } 
    267275 
    268276        return read; 
     
    328336 
    329337                FD_ZERO(&fds); 
    330                 if (!is_sending()) { 
     338                if ((!is_sending()) || conn == CONN_RAW_UDP) { 
    331339                        FD_SET(tun_fd, &fds); 
    332340                } 
     
    341349                        err(1, "select"); 
    342350 
    343                 if (i == 0) /* timeout */ 
     351                if (i == 0 && conn == CONN_DNS_NULL) /* timeout */ 
    344352                        send_ping(dns_fd); 
    345353                else { 
     
    359367 
    360368static void 
     369send_raw_data(int dns_fd) 
     370{ 
     371        send_raw(dns_fd, outpkt.data, outpkt.len, userid, RAW_HDR_CMD_DATA); 
     372} 
     373 
     374static void 
    361375send_chunk(int fd) 
    362376{ 
     
    508522send_raw_udp_login(int dns_fd, int userid, int seed) 
    509523{ 
    510         char buf[17]; 
     524        char buf[16]; 
    511525        login_calculate(buf, 16, password, seed + 1); 
    512         buf[16] = userid; 
    513  
    514         send_raw(dns_fd, buf, sizeof(buf), RAW_HDR_CMD_LOGIN); 
     526 
     527        send_raw(dns_fd, buf, sizeof(buf), userid, RAW_HDR_CMD_LOGIN); 
    515528} 
    516529 
     
    716729        if (!remoteaddr) { 
    717730                fprintf(stderr, " failed to get IP.\n"); 
    718                 return 1; 
     731                return 0; 
    719732        } 
    720733        fprintf(stderr, " at %s: ", inet_ntoa(server)); 
     
    744757                        /* recv() needed for windows, dont change to read() */ 
    745758                        len = recv(dns_fd, in, sizeof(in), 0); 
    746                         if (len >= (17 + RAW_HDR_LEN)) { 
     759                        if (len >= (16 + RAW_HDR_LEN)) { 
    747760                                char hash[16]; 
    748761                                login_calculate(hash, 16, password, seed - 1); 
    749762                                if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0 
    750                                         && in[RAW_HDR_CMD] == RAW_HDR_CMD_LOGIN  
    751                                         && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0 
    752                                         && in[16 + RAW_HDR_LEN] ==  userid) { 
     763                                        && RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN  
     764                                        && memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) { 
    753765 
    754766                                        fprintf(stderr, "OK\n"); 
    755                                         return 0; 
     767                                        return 1; 
    756768                                } 
    757769                        } 
     
    762774         
    763775        fprintf(stderr, "failed\n"); 
    764         return 1; 
     776        return 0; 
    765777} 
    766778 
     
    10171029        } 
    10181030 
    1019         handshake_raw_udp(dns_fd, seed); 
    1020  
    1021         case_preserved = handshake_case_check(dns_fd); 
    1022  
    1023         if (case_preserved) { 
    1024                 handshake_switch_codec(dns_fd); 
    1025         } 
    1026  
    1027         if (autodetect_frag_size) { 
    1028                 fragsize = handshake_autoprobe_fragsize(dns_fd); 
    1029                 if (!fragsize) { 
    1030                         return 1; 
    1031                 } 
    1032         } 
    1033  
    1034         handshake_set_fragsize(dns_fd, fragsize); 
     1031        if (handshake_raw_udp(dns_fd, seed)) { 
     1032                conn = CONN_RAW_UDP; 
     1033        } else { 
     1034                case_preserved = handshake_case_check(dns_fd); 
     1035 
     1036                if (case_preserved) { 
     1037                        handshake_switch_codec(dns_fd); 
     1038                } 
     1039 
     1040                if (autodetect_frag_size) { 
     1041                        fragsize = handshake_autoprobe_fragsize(dns_fd); 
     1042                        if (!fragsize) { 
     1043                                return 1; 
     1044                        } 
     1045                } 
     1046 
     1047                handshake_set_fragsize(dns_fd, fragsize); 
     1048        } 
    10351049 
    10361050        return 0; 
     
    11791193        b32 = get_base32_encoder(); 
    11801194        dataenc = get_base32_encoder(); 
     1195        conn = CONN_DNS_NULL; 
    11811196 
    11821197        retval = 0; 
     
    13131328        } 
    13141329         
    1315         fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr); 
     1330        if (conn == CONN_DNS_NULL) { 
     1331                fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr); 
     1332        } else { 
     1333                fprintf(stderr, "Sending raw traffic directly to %s\n", inet_ntoa(raw_serv.sin_addr)); 
     1334        } 
    13161335 
    13171336        if (foreground == 0)  
  • src/iodined.c

    ra62ae8 r58d961  
    8686#endif 
    8787 
    88 static int read_dns(int, struct query *); 
     88static int read_dns(int, int, struct query *); 
    8989static void write_dns(int, struct query *, char *, int); 
     90static void handle_full_packet(int, int); 
    9091 
    9192static void 
     
    296297{ 
    297298        struct in_addr tempip; 
    298         struct ip *hdr; 
    299         unsigned long outlen; 
    300299        char in[512]; 
    301300        char logindata[16]; 
     
    304303        char *tmp[2]; 
    305304        int userid; 
    306         int touser; 
    307305        int version; 
    308306        int code; 
     
    590588 
    591589                        if (lastfrag & 1) { /* packet is complete */ 
    592                                 int ret; 
    593                                 outlen = sizeof(out); 
    594                                 ret = uncompress((uint8_t*)out, &outlen,  
    595                                            (uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len); 
    596  
    597                                 if (ret == Z_OK) { 
    598                                         hdr = (struct ip*) (out + 4); 
    599                                         touser = find_user_by_ip(hdr->ip_dst.s_addr); 
    600  
    601                                         if (touser == -1) { 
    602                                                 /* send the uncompressed packet to tun device */ 
    603                                                 write_tun(tun_fd, out, outlen); 
    604                                         } else { 
    605                                                 /* send the compressed packet to other client 
    606                                                  * if another packet is queued, throw away this one. TODO build queue */ 
    607                                                 if (users[touser].outpacket.len == 0) { 
    608                                                         memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len); 
    609                                                         users[touser].outpacket.len = users[userid].inpacket.len; 
    610                                                 } 
    611                                         } 
    612                                 } else { 
    613                                         fprintf(stderr, "Discarded data, uncompress() result: %d\n", ret); 
    614                                 } 
    615                                 users[userid].inpacket.len = users[userid].inpacket.offset = 0; 
     590                                handle_full_packet(tun_fd, userid); 
    616591                        } 
    617592                        /* Update seqno and maybe send immediate response packet */ 
     
    731706        int inside_topdomain; 
    732707 
    733         if ((read = read_dns(dns_fd, &q)) <= 0) 
     708        if ((read = read_dns(dns_fd, tun_fd, &q)) <= 0) 
    734709                return 0; 
    735710 
     
    821796                        } 
    822797                } else { 
    823                         if(FD_ISSET(tun_fd, &fds)) { 
     798                        if (FD_ISSET(tun_fd, &fds)) { 
    824799                                tunnel_tun(tun_fd, dns_fd); 
    825800                                continue; 
    826801                        } 
    827                         if(FD_ISSET(dns_fd, &fds)) { 
     802                        if (FD_ISSET(dns_fd, &fds)) { 
    828803                                tunnel_dns(tun_fd, dns_fd, bind_fd); 
    829804                                continue; 
    830805                        }  
    831                         if(FD_ISSET(bind_fd, &fds)) { 
     806                        if (FD_ISSET(bind_fd, &fds)) { 
    832807                                tunnel_bind(bind_fd, dns_fd); 
    833808                                continue; 
     
    840815 
    841816static void 
    842 send_raw(int fd, char *buf, int buflen, int cmd, struct query *q) 
     817handle_full_packet(int tun_fd, int userid) 
     818{ 
     819        unsigned long outlen; 
     820        char out[64*1024]; 
     821        int touser; 
     822        int ret; 
     823 
     824        outlen = sizeof(out); 
     825        ret = uncompress((uint8_t*)out, &outlen,  
     826                   (uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len); 
     827 
     828        if (ret == Z_OK) { 
     829                struct ip *hdr; 
     830 
     831                hdr = (struct ip*) (out + 4); 
     832                touser = find_user_by_ip(hdr->ip_dst.s_addr); 
     833 
     834                if (touser == -1) { 
     835                        /* send the uncompressed packet to tun device */ 
     836                        write_tun(tun_fd, out, outlen); 
     837                } else { 
     838                        /* send the compressed packet to other client 
     839                         * if another packet is queued, throw away this one. TODO build queue */ 
     840                        if (users[touser].outpacket.len == 0) { 
     841                                memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len); 
     842                                users[touser].outpacket.len = users[userid].inpacket.len; 
     843                        } 
     844                } 
     845        } else { 
     846                fprintf(stderr, "Discarded data, uncompress() result: %d\n", ret); 
     847        } 
     848        users[userid].inpacket.len = users[userid].inpacket.offset = 0; 
     849} 
     850 
     851static void 
     852send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q) 
    843853{ 
    844854        char packet[4096]; 
     
    851861 
    852862        len += RAW_HDR_LEN; 
    853         packet[RAW_HDR_CMD] = cmd; 
     863        packet[RAW_HDR_CMD] = cmd | (user & 0x0F); 
    854864 
    855865        sendto(fd, packet, len, 0, &q->from, q->fromlen); 
     
    857867 
    858868static void 
    859 handle_raw_login(char *packet, int len, struct query *q, int fd) 
    860 { 
    861         int userid; 
     869handle_raw_login(char *packet, int len, struct query *q, int fd, int userid) 
     870{ 
    862871        char myhash[16]; 
    863872         
    864         if (len < 17) return; 
    865  
    866         userid = packet[16]; 
     873        if (len < 16) return; 
     874 
    867875        if (userid < 0 || userid > created_users) return; 
    868876        if (!users[userid].active) return; 
    869877 
     878        /* User sends hash of seed + 1 */ 
    870879        login_calculate(myhash, 16, password, users[userid].seed + 1); 
    871880        if (memcmp(packet, myhash, 16) == 0) { 
     881                struct sockaddr_in *tempin; 
     882 
     883                /* Update query and time info for user */ 
     884                users[userid].last_pkt = time(NULL); 
     885                memcpy(&(users[userid].q), q, sizeof(struct query)); 
     886 
     887                /* Store remote IP number */ 
     888                tempin = (struct sockaddr_in *) &(q->from); 
     889                memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); 
     890                  
    872891                /* Correct hash, reply with hash of seed - 1 */ 
     892                user_set_conn_type(userid, CONN_RAW_UDP); 
    873893                users[userid].last_pkt = time(NULL); 
    874894                login_calculate(myhash, 16, password, users[userid].seed - 1); 
    875                 memcpy(packet, myhash, 16); 
    876                 send_raw(fd, packet, 17, RAW_HDR_CMD_LOGIN, q); 
    877         } 
     895                send_raw(fd, myhash, 16, userid, RAW_HDR_CMD_LOGIN, q); 
     896        } 
     897} 
     898 
     899static void 
     900handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, int userid) 
     901{ 
     902        if (check_user_and_ip(userid, q) != 0) { 
     903                return; 
     904        } 
     905 
     906        /* Update query and time info for user */ 
     907        users[userid].last_pkt = time(NULL); 
     908        memcpy(&(users[userid].q), q, sizeof(struct query)); 
     909 
     910        /* copy to packet buffer, update length */ 
     911        users[userid].inpacket.offset = 0; 
     912        memcpy(users[userid].inpacket.data, packet, len); 
     913        users[userid].inpacket.len = len; 
     914 
     915        if (debug >= 1) { 
     916                fprintf(stderr, "IN   pkt raw, total %d, from user %d\n", 
     917                        users[userid].inpacket.len, userid); 
     918        } 
     919 
     920        handle_full_packet(tun_fd, userid); 
    878921} 
    879922 
    880923static int 
    881 raw_decode(char *packet, int len, struct query *q, int fd) 
    882 { 
     924raw_decode(char *packet, int len, struct query *q, int dns_fd, int tun_fd) 
     925{ 
     926        int raw_user; 
     927 
    883928        /* minimum length */ 
    884929        if (len < RAW_HDR_LEN) return 0; 
     
    886931        if (memcmp(packet, raw_header, RAW_HDR_IDENT_LEN)) return 0; 
    887932 
    888         if (packet[RAW_HDR_CMD] == RAW_HDR_CMD_LOGIN) { 
    889                 handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, fd); 
    890         } else { 
    891                 warnx("Unhandled raw command %02X\n", packet[RAW_HDR_CMD]); 
     933        raw_user = RAW_HDR_GET_USR(packet); 
     934        printf("raw %02x\n", packet[RAW_HDR_CMD]); 
     935        switch (RAW_HDR_GET_CMD(packet)) { 
     936        case RAW_HDR_CMD_LOGIN: 
     937                /* Login challenge */ 
     938                handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, raw_user); 
     939                break; 
     940        case RAW_HDR_CMD_DATA: 
     941                /* Data packet */ 
     942                handle_raw_data(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, tun_fd, raw_user); 
     943                break; 
     944        default: 
     945                warnx("Unhandled raw command %02X from user %d", RAW_HDR_GET_CMD(packet), raw_user); 
     946                break; 
    892947        } 
    893948        return 1; 
     
    895950 
    896951static int 
    897 read_dns(int fd, struct query *q) 
     952read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw_decode() below */ 
    898953{ 
    899954        struct sockaddr_in from; 
     
    930985 
    931986                /* TODO do not handle raw packets here! */ 
    932                 if (raw_decode(packet, r, q, fd)) { 
     987                if (raw_decode(packet, r, q, fd, tun_fd)) { 
    933988                        return 0; 
    934989                } 
     
    11781233 
    11791234        topdomain = strdup(argv[1]); 
    1180         if(strlen(topdomain) <= 128) { 
     1235        if (strlen(topdomain) <= 128) { 
    11811236                if(check_topdomain(topdomain)) { 
    11821237                        warnx("Topdomain contains invalid characters."); 
  • src/user.c

    r541959 r58d961  
    9191                users[i].out_acked_fragment = 0; 
    9292                users[i].fragsize = 4096; 
     93                users[i].conn = CONN_DNS_NULL; 
    9394        } 
    9495 
     
    162163                        users[i].active = 1; 
    163164                        users[i].last_pkt = time(NULL); 
     165                        users[i].fragsize = 4096; 
     166                        users[i].conn = CONN_DNS_NULL; 
    164167                        ret = i; 
    165168                        break; 
     
    177180        users[userid].encoder = enc; 
    178181} 
     182 
     183void 
     184user_set_conn_type(int userid, enum connection c) 
     185{ 
     186        if (userid < 0 || userid >= USERS) 
     187                return; 
     188 
     189        if (c < 0 || c >= CONN_MAX) 
     190                return; 
     191         
     192        users[userid].conn = c; 
     193} 
     194         
  • src/user.h

    rd4e077 r58d961  
    3535        int out_acked_fragment; 
    3636        int fragsize; 
     37        enum connection conn; 
    3738}; 
    3839 
     
    4546int find_available_user(); 
    4647void user_switch_codec(int userid, struct encoder *enc); 
     48void user_set_conn_type(int userid, enum connection c); 
    4749 
    4850#endif 
Note: See TracChangeset for help on using the changeset viewer.