Implemented new protocol for upstream data
This commit is contained in:
parent
2c4c5ec1ba
commit
8d27febc7d
|
@ -38,8 +38,8 @@ Server replies:
|
||||||
Switch codec:
|
Switch codec:
|
||||||
Client sends:
|
Client sends:
|
||||||
First byte s or S
|
First byte s or S
|
||||||
One byte ASCII digit, meaning userid
|
5 bits coded as Base32 char, meaning userid
|
||||||
One byte ASCII digit, with value 5 or 6, representing number of raw
|
5 bits coded as Base32 char, with value 5 or 6, representing number of raw
|
||||||
bits per encoded byte
|
bits per encoded byte
|
||||||
Server sends:
|
Server sends:
|
||||||
Name of codec if accepted. After this all upstream data packets must
|
Name of codec if accepted. After this all upstream data packets must
|
||||||
|
@ -47,28 +47,28 @@ Server sends:
|
||||||
BADCODEC if not accepted. Client must then revert to Base32
|
BADCODEC if not accepted. Client must then revert to Base32
|
||||||
|
|
||||||
Data:
|
Data:
|
||||||
Upstream data header (encoded as 4 bytes Base32):
|
Upstream data header:
|
||||||
4321 0 432 10 43 210 4321 0
|
3210 432 10 43 210 4321 0
|
||||||
+----+-+---+--+--+---+----+-+
|
+----+---+--+--+---+----+-+
|
||||||
|UUUU|L|SSS|FF|FF|DDD|GGGG|C|
|
|UUUU|SSS|FF|FF|DDD|GGGG|L|
|
||||||
+----+-+---+--+--+---+----+-+
|
+----+---+--+--+---+----+-+
|
||||||
|
|
||||||
Downstream data header:
|
Downstream data header:
|
||||||
7 654 3210 765 4321 0
|
7 654 3210 765 4321 0
|
||||||
+-+---+----+---+----+-+
|
+-+---+----+---+----+-+
|
||||||
|L|SSS|FFFF|DDD|GGGG|C|
|
|C|SSS|FFFF|DDD|GGGG|L|
|
||||||
+-+---+----+---+----+-+
|
+-+---+----+---+----+-+
|
||||||
|
|
||||||
UUUU = Userid
|
UUUU = Userid
|
||||||
L = Last fragment in packet flag
|
L = Last fragment in packet flag
|
||||||
SSS = Upstream packet sequence number
|
SS = Upstream packet sequence number
|
||||||
FFFF = Upstream fragment number
|
FFFF = Upstream fragment number
|
||||||
DDD = Downstream packet sequence number
|
DDD = Downstream packet sequence number
|
||||||
GGGG = Downstream fragment number
|
GGGG = Downstream fragment number
|
||||||
C = Compression enabled for this packet
|
C = Compression enabled for downstream packet
|
||||||
|
|
||||||
Upstream data packet starts with 4 bytes Base32 encoded header, then comes
|
Upstream data packet starts with 1 byte ASCII hex coded user byte, then 3 bytes
|
||||||
the payload data, encoded with chosen codec.
|
Base32 encoded header, then comes the payload data, encoded with chosen codec.
|
||||||
|
|
||||||
Downstream data starts with 2 byte header. Then payload data, which may be
|
Downstream data starts with 2 byte header. Then payload data, which may be
|
||||||
compressed.
|
compressed.
|
||||||
|
@ -77,7 +77,10 @@ Ping:
|
||||||
Client sends:
|
Client sends:
|
||||||
First byte p or P
|
First byte p or P
|
||||||
Rest encoded with Base32:
|
Rest encoded with Base32:
|
||||||
1 byte userid
|
1 byte with 4 bits userid
|
||||||
|
1 byte with:
|
||||||
|
3 bits downstream seqno
|
||||||
|
4 bits downstream fragment
|
||||||
CMC
|
CMC
|
||||||
|
|
||||||
The server response to Ping and Data packets is a DNS NULL type response:
|
The server response to Ping and Data packets is a DNS NULL type response:
|
||||||
|
|
|
@ -35,7 +35,7 @@ inline_dotify(char *buf, size_t buflen)
|
||||||
char *reader, *writer;
|
char *reader, *writer;
|
||||||
|
|
||||||
total = strlen(buf);
|
total = strlen(buf);
|
||||||
dots = total / 62;
|
dots = total / 57;
|
||||||
|
|
||||||
writer = buf;
|
writer = buf;
|
||||||
writer += total;
|
writer += total;
|
||||||
|
@ -52,7 +52,7 @@ inline_dotify(char *buf, size_t buflen)
|
||||||
pos = (unsigned) (reader - buf) + 1;
|
pos = (unsigned) (reader - buf) + 1;
|
||||||
|
|
||||||
while (dots) {
|
while (dots) {
|
||||||
if (pos % 62 == 0) {
|
if (pos % 57 == 0) {
|
||||||
*writer-- = '.';
|
*writer-- = '.';
|
||||||
dots--;
|
dots--;
|
||||||
}
|
}
|
||||||
|
|
52
src/iodine.c
52
src/iodine.c
|
@ -124,10 +124,9 @@ build_hostname(char *buf, size_t buflen,
|
||||||
size_t space;
|
size_t space;
|
||||||
char *b;
|
char *b;
|
||||||
|
|
||||||
|
space = MIN(0xFF, buflen) - strlen(topdomain) - 5;
|
||||||
space = MIN(0xFF, buflen) - strlen(topdomain) - 2;
|
|
||||||
if (!encoder->places_dots())
|
if (!encoder->places_dots())
|
||||||
space -= (space / 62); /* space for dots */
|
space -= (space / 57); /* space for dots */
|
||||||
|
|
||||||
memset(buf, 0, buflen);
|
memset(buf, 0, buflen);
|
||||||
|
|
||||||
|
@ -209,6 +208,8 @@ tunnel_tun(int tun_fd, int dns_fd)
|
||||||
packet.sentlen = 0;
|
packet.sentlen = 0;
|
||||||
packet.offset = 0;
|
packet.offset = 0;
|
||||||
packet.len = outlen;
|
packet.len = outlen;
|
||||||
|
packet.seqno++;
|
||||||
|
packet.fragment = 0;
|
||||||
|
|
||||||
send_chunk(dns_fd);
|
send_chunk(dns_fd);
|
||||||
|
|
||||||
|
@ -254,9 +255,11 @@ tunnel(int tun_fd, int dns_fd)
|
||||||
tv.tv_sec = 1;
|
tv.tv_sec = 1;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
if (!is_sending())
|
if (!is_sending()) {
|
||||||
FD_SET(tun_fd, &fds);
|
FD_SET(tun_fd, &fds);
|
||||||
|
}
|
||||||
FD_SET(dns_fd, &fds);
|
FD_SET(dns_fd, &fds);
|
||||||
|
|
||||||
i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
|
i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
|
||||||
|
@ -297,15 +300,21 @@ send_chunk(int fd)
|
||||||
p += packet.offset;
|
p += packet.offset;
|
||||||
avail = packet.len - packet.offset;
|
avail = packet.len - packet.offset;
|
||||||
|
|
||||||
packet.sentlen = build_hostname(buf + 1, sizeof(buf) - 1, p, avail, topdomain, dataenc);
|
packet.sentlen = build_hostname(buf + 4, sizeof(buf) - 4, p, avail, topdomain, dataenc);
|
||||||
|
packet.fragment++;
|
||||||
|
|
||||||
if (packet.sentlen == avail)
|
/* Build upstream data header (see doc/proto_xxxxxxxx.txt) */
|
||||||
code = 1;
|
|
||||||
else
|
buf[0] = hex[userid & 15]; /* First byte is 4 bits userid */
|
||||||
code = 0;
|
|
||||||
|
code = ((packet.seqno & 7) << 2) | ((packet.fragment & 15) >> 2);
|
||||||
code |= (userid << 1);
|
buf[1] = b32_5to8(code); /* Second byte is 3 bits seqno, 2 upper bits fragment count */
|
||||||
buf[0] = hex[code];
|
|
||||||
|
code = ((packet.fragment & 3) << 3) | (0);
|
||||||
|
buf[2] = b32_5to8(code); /* Third byte is 2 bits lower fragment count, 3 bits downstream packet seqno */
|
||||||
|
|
||||||
|
code = (0 << 1) | (packet.sentlen == avail);
|
||||||
|
buf[3] = b32_5to8(code); /* Fourth byte is 4 bits downstream fragment count, 1 bit compression flag */
|
||||||
|
|
||||||
send_query(fd, buf);
|
send_query(fd, buf);
|
||||||
}
|
}
|
||||||
|
@ -330,7 +339,7 @@ send_login(int fd, char *login, int len)
|
||||||
static void
|
static void
|
||||||
send_ping(int fd)
|
send_ping(int fd)
|
||||||
{
|
{
|
||||||
char data[3];
|
char data[4];
|
||||||
|
|
||||||
if (is_sending()) {
|
if (is_sending()) {
|
||||||
packet.sentlen = 0;
|
packet.sentlen = 0;
|
||||||
|
@ -339,8 +348,9 @@ send_ping(int fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
data[0] = userid;
|
data[0] = userid;
|
||||||
data[1] = (rand_seed >> 8) & 0xff;
|
data[1] = 0;
|
||||||
data[2] = (rand_seed >> 0) & 0xff;
|
data[2] = (rand_seed >> 8) & 0xff;
|
||||||
|
data[3] = (rand_seed >> 0) & 0xff;
|
||||||
|
|
||||||
rand_seed++;
|
rand_seed++;
|
||||||
|
|
||||||
|
@ -380,13 +390,9 @@ send_case_check(int fd)
|
||||||
static void
|
static void
|
||||||
send_codec_switch(int fd, int userid, int bits)
|
send_codec_switch(int fd, int userid, int bits)
|
||||||
{
|
{
|
||||||
char buf[512] = "S00.";
|
char buf[512] = "S__.";
|
||||||
if (userid >= 0 && userid < 9) {
|
buf[1] = b32_5to8(userid);
|
||||||
buf[1] += userid;
|
buf[2] = b32_5to8(bits);
|
||||||
}
|
|
||||||
if (bits >= 0 && bits < 9) {
|
|
||||||
buf[2] += bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncat(buf, topdomain, 512 - strlen(buf));
|
strncat(buf, topdomain, 512 - strlen(buf));
|
||||||
send_query(fd, buf);
|
send_query(fd, buf);
|
||||||
|
@ -705,6 +711,8 @@ main(int argc, char **argv)
|
||||||
device = NULL;
|
device = NULL;
|
||||||
chunkid = 0;
|
chunkid = 0;
|
||||||
|
|
||||||
|
packet.seqno = 0;
|
||||||
|
|
||||||
b32 = get_base32_encoder();
|
b32 = get_base32_encoder();
|
||||||
dataenc = get_base32_encoder();
|
dataenc = get_base32_encoder();
|
||||||
|
|
||||||
|
|
151
src/iodined.c
151
src/iodined.c
|
@ -151,6 +151,33 @@ send_version_response(int fd, version_ack_t ack, uint32_t payload, int userid, s
|
||||||
write_dns(fd, q, out, sizeof(out));
|
write_dns(fd, q, out, sizeof(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_downstream_seqno(int dns_fd, int userid, int down_seq, int down_frag)
|
||||||
|
{
|
||||||
|
/* update outgoing seqno/frag */
|
||||||
|
if (down_seq != users[userid].out_acked_seqno) {
|
||||||
|
/* First ack on new outgoing packet */
|
||||||
|
users[userid].out_acked_seqno = down_seq;
|
||||||
|
users[userid].out_acked_fragment = down_frag;
|
||||||
|
} else {
|
||||||
|
if (down_frag > users[userid].out_acked_fragment) {
|
||||||
|
/* Ack on later fragment */
|
||||||
|
users[userid].out_acked_fragment = down_frag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send reply if waiting */
|
||||||
|
if (users[userid].outpacket.len > 0) {
|
||||||
|
if (debug >= 1) {
|
||||||
|
printf("OUT pkt seq# %d, frag %d (last=%d), fragsize %d of total %d, to user %d\n",
|
||||||
|
0, 0, 1, users[userid].outpacket.len, users[userid].outpacket.len, userid);
|
||||||
|
}
|
||||||
|
write_dns(dns_fd, &users[userid].q, users[userid].outpacket.data, users[userid].outpacket.len);
|
||||||
|
users[userid].outpacket.len = 0;
|
||||||
|
users[userid].q.id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
||||||
{
|
{
|
||||||
|
@ -240,16 +267,6 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if(in[0] == 'P' || in[0] == 'p') {
|
|
||||||
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
|
|
||||||
/* Ping packet, store userid */
|
|
||||||
userid = unpacked[0];
|
|
||||||
if (userid < 0 || userid >= USERS || ip_cmp(userid, q) != 0) {
|
|
||||||
write_dns(dns_fd, q, "BADIP", 5);
|
|
||||||
return; /* illegal id */
|
|
||||||
}
|
|
||||||
memcpy(&(users[userid].q), q, sizeof(struct query));
|
|
||||||
users[userid].last_pkt = time(NULL);
|
|
||||||
} else if(in[0] == 'Z' || in[0] == 'z') {
|
} else if(in[0] == 'Z' || in[0] == 'z') {
|
||||||
/* Check for case conservation and chars not allowed according to RFC */
|
/* Check for case conservation and chars not allowed according to RFC */
|
||||||
|
|
||||||
|
@ -264,14 +281,15 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
userid = in[1] & 0x7;
|
userid = b32_8to5(in[1]);
|
||||||
|
|
||||||
if (ip_cmp(userid, q) != 0) {
|
if (ip_cmp(userid, q) != 0) {
|
||||||
write_dns(dns_fd, q, "BADIP", 5);
|
write_dns(dns_fd, q, "BADIP", 5);
|
||||||
return; /* illegal id */
|
return; /* illegal id */
|
||||||
}
|
}
|
||||||
|
|
||||||
codec = in[2] & 0xF;
|
codec = b32_8to5(in[2]);
|
||||||
|
|
||||||
switch (codec) {
|
switch (codec) {
|
||||||
case 5: /* 5 bits per byte = base32 */
|
case 5: /* 5 bits per byte = base32 */
|
||||||
enc = get_base32_encoder();
|
enc = get_base32_encoder();
|
||||||
|
@ -288,6 +306,25 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if(in[0] == 'P' || in[0] == 'p') {
|
||||||
|
int dn_seq;
|
||||||
|
int dn_frag;
|
||||||
|
|
||||||
|
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1, b32);
|
||||||
|
/* Ping packet, store userid */
|
||||||
|
userid = unpacked[0];
|
||||||
|
if (userid < 0 || userid >= USERS || ip_cmp(userid, q) != 0) {
|
||||||
|
write_dns(dns_fd, q, "BADIP", 5);
|
||||||
|
return; /* illegal id */
|
||||||
|
}
|
||||||
|
|
||||||
|
dn_seq = unpacked[1] >> 4;
|
||||||
|
dn_frag = unpacked[1] & 15;
|
||||||
|
memcpy(&(users[userid].q), q, sizeof(struct query));
|
||||||
|
users[userid].last_pkt = time(NULL);
|
||||||
|
|
||||||
|
/* Update seqno and maybe send immediate response packet */
|
||||||
|
update_downstream_seqno(dns_fd, userid, dn_seq, dn_frag);
|
||||||
} else if((in[0] >= '0' && in[0] <= '9')
|
} else if((in[0] >= '0' && in[0] <= '9')
|
||||||
|| (in[0] >= 'a' && in[0] <= 'f')
|
|| (in[0] >= 'a' && in[0] <= 'f')
|
||||||
|| (in[0] >= 'A' && in[0] <= 'F')) {
|
|| (in[0] >= 'A' && in[0] <= 'F')) {
|
||||||
|
@ -298,7 +335,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
||||||
if ((in[0] >= 'A' && in[0] <= 'F'))
|
if ((in[0] >= 'A' && in[0] <= 'F'))
|
||||||
code = in[0] - 'A' + 10;
|
code = in[0] - 'A' + 10;
|
||||||
|
|
||||||
userid = code >> 1;
|
userid = code;
|
||||||
if (userid < 0 || userid >= USERS) {
|
if (userid < 0 || userid >= USERS) {
|
||||||
write_dns(dns_fd, q, "BADIP", 5);
|
write_dns(dns_fd, q, "BADIP", 5);
|
||||||
return; /* illegal id */
|
return; /* illegal id */
|
||||||
|
@ -308,45 +345,69 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
||||||
if (check_ip && ip_cmp(userid, q) != 0) {
|
if (check_ip && ip_cmp(userid, q) != 0) {
|
||||||
write_dns(dns_fd, q, "BADIP", 5);
|
write_dns(dns_fd, q, "BADIP", 5);
|
||||||
} else {
|
} else {
|
||||||
/* decode with this users encoding */
|
/* Decode data header */
|
||||||
read = unpack_data(unpacked, sizeof(unpacked), &(in[1]), domain_len - 1,
|
int up_seq = (b32_8to5(in[1]) >> 2) & 7;
|
||||||
users[userid].encoder);
|
int up_frag = ((b32_8to5(in[1]) & 3) << 2) | ((b32_8to5(in[2]) >> 3) & 3);
|
||||||
|
int dn_seq = (b32_8to5(in[2]) & 7);
|
||||||
|
int dn_frag = b32_8to5(in[3]) >> 1;
|
||||||
|
int lastfrag = b32_8to5(in[3]) & 1;
|
||||||
|
|
||||||
|
/* Update query and time info for user */
|
||||||
users[userid].last_pkt = time(NULL);
|
users[userid].last_pkt = time(NULL);
|
||||||
memcpy(&(users[userid].q), q, sizeof(struct query));
|
memcpy(&(users[userid].q), q, sizeof(struct query));
|
||||||
|
|
||||||
|
if (up_seq != users[userid].inpacket.seqno) {
|
||||||
|
/* New packet has arrived */
|
||||||
|
users[userid].inpacket.seqno = up_seq;
|
||||||
|
users[userid].inpacket.len = 0;
|
||||||
|
users[userid].inpacket.offset = 0;
|
||||||
|
}
|
||||||
|
users[userid].inpacket.fragment = up_frag;
|
||||||
|
|
||||||
|
/* decode with this users encoding */
|
||||||
|
read = unpack_data(unpacked, sizeof(unpacked), &(in[4]), domain_len - 4,
|
||||||
|
users[userid].encoder);
|
||||||
|
|
||||||
|
/* copy to packet buffer, update length */
|
||||||
memcpy(users[userid].inpacket.data + users[userid].inpacket.offset, unpacked, read);
|
memcpy(users[userid].inpacket.data + users[userid].inpacket.offset, unpacked, read);
|
||||||
users[userid].inpacket.len += read;
|
users[userid].inpacket.len += read;
|
||||||
users[userid].inpacket.offset += read;
|
users[userid].inpacket.offset += read;
|
||||||
|
|
||||||
if (code & 1) {
|
if (debug >= 1) {
|
||||||
|
printf("IN pkt seq# %d, frag %d (last=%d), fragsize %d, total %d, from user %d\n",
|
||||||
|
up_seq, up_frag, lastfrag, read, users[userid].inpacket.len, userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastfrag & 1) { /* packet is complete */
|
||||||
|
int ret;
|
||||||
outlen = sizeof(out);
|
outlen = sizeof(out);
|
||||||
uncompress((uint8_t*)out, &outlen,
|
ret = uncompress((uint8_t*)out, &outlen,
|
||||||
(uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len);
|
(uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len);
|
||||||
|
|
||||||
hdr = (struct ip*) (out + 4);
|
if (ret == Z_OK) {
|
||||||
touser = find_user_by_ip(hdr->ip_dst.s_addr);
|
hdr = (struct ip*) (out + 4);
|
||||||
|
touser = find_user_by_ip(hdr->ip_dst.s_addr);
|
||||||
|
|
||||||
if (touser == -1) {
|
if (touser == -1) {
|
||||||
/* send the uncompressed packet to tun device */
|
/* send the uncompressed packet to tun device */
|
||||||
write_tun(tun_fd, out, outlen);
|
write_tun(tun_fd, out, outlen);
|
||||||
} else {
|
} else {
|
||||||
/* send the compressed packet to other client
|
/* send the compressed packet to other client
|
||||||
* if another packet is queued, throw away this one. TODO build queue */
|
* if another packet is queued, throw away this one. TODO build queue */
|
||||||
if (users[touser].outpacket.len == 0) {
|
if (users[touser].outpacket.len == 0) {
|
||||||
memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len);
|
memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len);
|
||||||
users[touser].outpacket.len = users[userid].inpacket.len;
|
users[touser].outpacket.len = users[userid].inpacket.len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
printf("Discarded data, uncompress() result: %d\n", ret);
|
||||||
}
|
}
|
||||||
users[userid].inpacket.len = users[userid].inpacket.offset = 0;
|
users[userid].inpacket.len = users[userid].inpacket.offset = 0;
|
||||||
}
|
}
|
||||||
|
/* Update seqno and maybe send immediate response packet */
|
||||||
|
update_downstream_seqno(dns_fd, userid, dn_seq, dn_frag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* userid must be set for a reply to be sent */
|
|
||||||
if (userid >= 0 && userid < USERS && ip_cmp(userid, q) == 0 && users[userid].outpacket.len > 0) {
|
|
||||||
write_dns(dns_fd, q, users[userid].outpacket.data, users[userid].outpacket.len);
|
|
||||||
users[userid].outpacket.len = 0;
|
|
||||||
users[userid].q.id = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -361,7 +422,7 @@ handle_ns_request(int dns_fd, struct query *q)
|
||||||
|
|
||||||
len = dns_encode_ns_response(buf, sizeof(buf), q, topdomain);
|
len = dns_encode_ns_response(buf, sizeof(buf), q, topdomain);
|
||||||
|
|
||||||
if (debug >= 1) {
|
if (debug >= 2) {
|
||||||
struct sockaddr_in *tempin;
|
struct sockaddr_in *tempin;
|
||||||
tempin = (struct sockaddr_in *) &(q->from);
|
tempin = (struct sockaddr_in *) &(q->from);
|
||||||
printf("TX: client %s, type %d, name %s, %d bytes NS reply\n",
|
printf("TX: client %s, type %d, name %s, %d bytes NS reply\n",
|
||||||
|
@ -394,7 +455,7 @@ forward_query(int bind_fd, struct query *q)
|
||||||
memcpy(&(myaddr->sin_addr), &newaddr, sizeof(in_addr_t));
|
memcpy(&(myaddr->sin_addr), &newaddr, sizeof(in_addr_t));
|
||||||
myaddr->sin_port = htons(bind_port);
|
myaddr->sin_port = htons(bind_port);
|
||||||
|
|
||||||
if (debug >= 1) {
|
if (debug >= 2) {
|
||||||
printf("TX: NS reply \n");
|
printf("TX: NS reply \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,18 +483,18 @@ tunnel_bind(int bind_fd, int dns_fd)
|
||||||
|
|
||||||
id = dns_get_id(packet, r);
|
id = dns_get_id(packet, r);
|
||||||
|
|
||||||
if (debug >= 1) {
|
if (debug >= 2) {
|
||||||
printf("RX: Got response on query %u from DNS\n", (id & 0xFFFF));
|
printf("RX: Got response on query %u from DNS\n", (id & 0xFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get sockaddr from id */
|
/* Get sockaddr from id */
|
||||||
fw_query_get(id, &query);
|
fw_query_get(id, &query);
|
||||||
if (!query && debug >= 1) {
|
if (!query && debug >= 2) {
|
||||||
printf("Lost sender of id %u, dropping reply\n", (id & 0xFFFF));
|
printf("Lost sender of id %u, dropping reply\n", (id & 0xFFFF));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug >= 1) {
|
if (debug >= 2) {
|
||||||
struct sockaddr_in *in;
|
struct sockaddr_in *in;
|
||||||
in = (struct sockaddr_in *) &(query->addr);
|
in = (struct sockaddr_in *) &(query->addr);
|
||||||
printf("TX: client %s id %u, %d bytes\n",
|
printf("TX: client %s id %u, %d bytes\n",
|
||||||
|
@ -460,7 +521,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd)
|
||||||
if ((read = read_dns(dns_fd, &q)) <= 0)
|
if ((read = read_dns(dns_fd, &q)) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (debug >= 1) {
|
if (debug >= 2) {
|
||||||
struct sockaddr_in *tempin;
|
struct sockaddr_in *tempin;
|
||||||
tempin = (struct sockaddr_in *) &(q.from);
|
tempin = (struct sockaddr_in *) &(q.from);
|
||||||
printf("RX: client %s, type %d, name %s\n",
|
printf("RX: client %s, type %d, name %s\n",
|
||||||
|
@ -543,6 +604,10 @@ tunnel(int tun_fd, int dns_fd, int bind_fd)
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < USERS; j++) {
|
for (j = 0; j < USERS; j++) {
|
||||||
if (users[j].q.id != 0) {
|
if (users[j].q.id != 0) {
|
||||||
|
if (debug >= 1) {
|
||||||
|
printf("OUT pkt seq# %d, frag %d (last=%d), fragsize %d of total %d, to user %d\n",
|
||||||
|
0, 0, 1, users[j].outpacket.len, users[j].outpacket.len, j);
|
||||||
|
}
|
||||||
write_dns(dns_fd, &(users[j].q), users[j].outpacket.data, users[j].outpacket.len);
|
write_dns(dns_fd, &(users[j].q), users[j].outpacket.data, users[j].outpacket.len);
|
||||||
users[j].outpacket.len = 0;
|
users[j].outpacket.len = 0;
|
||||||
users[j].q.id = 0;
|
users[j].q.id = 0;
|
||||||
|
@ -626,7 +691,7 @@ write_dns(int fd, struct query *q, char *data, int datalen)
|
||||||
|
|
||||||
len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, data, datalen);
|
len = dns_encode(buf, sizeof(buf), q, QR_ANSWER, data, datalen);
|
||||||
|
|
||||||
if (debug >= 1) {
|
if (debug >= 2) {
|
||||||
struct sockaddr_in *tempin;
|
struct sockaddr_in *tempin;
|
||||||
tempin = (struct sockaddr_in *) &(q->from);
|
tempin = (struct sockaddr_in *) &(q->from);
|
||||||
printf("TX: client %s, type %d, name %s, %d bytes data\n",
|
printf("TX: client %s, type %d, name %s, %d bytes data\n",
|
||||||
|
|
|
@ -50,6 +50,8 @@ init_users(in_addr_t my_ip)
|
||||||
users[i].inpacket.offset = 0;
|
users[i].inpacket.offset = 0;
|
||||||
users[i].outpacket.len = 0;
|
users[i].outpacket.len = 0;
|
||||||
users[i].q.id = 0;
|
users[i].q.id = 0;
|
||||||
|
users[i].out_acked_seqno = 0;
|
||||||
|
users[i].out_acked_fragment = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#ifndef __USER_H__
|
#ifndef __USER_H__
|
||||||
#define __USER_H__
|
#define __USER_H__
|
||||||
|
|
||||||
#define USERS 8
|
#define USERS 16
|
||||||
|
|
||||||
struct user {
|
struct user {
|
||||||
char id;
|
char id;
|
||||||
|
@ -30,6 +30,8 @@ struct user {
|
||||||
struct packet inpacket;
|
struct packet inpacket;
|
||||||
struct packet outpacket;
|
struct packet outpacket;
|
||||||
struct encoder *encoder;
|
struct encoder *encoder;
|
||||||
|
int out_acked_seqno;
|
||||||
|
int out_acked_fragment;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct user users[USERS];
|
extern struct user users[USERS];
|
||||||
|
|
Loading…
Reference in New Issue