#36, add way to request ip address from server

This commit is contained in:
Erik Ekman 2009-06-11 19:52:42 +00:00 committed by Erik Ekman
parent 894ca25968
commit 27fc039700
3 changed files with 155 additions and 1 deletions

125
doc/proto_00000501.txt Normal file
View File

@ -0,0 +1,125 @@
Detailed specification of protocol in version 00000501
======================================================
Note: work in progress!!
======================================================
CMC = 2 byte Cache Miss Counter, increased every time it is used
Version:
Client sends:
First byte v or V
Rest encoded with base32:
4 bytes big endian protocol version
CMC
Server replies:
4 chars:
VACK (version ok), followed by login challenge
VNAK (version differs), followed by server protocol version
VFUL (server has no free slots), followed by max users
4 byte value: means login challenge/server protocol version/max users
1 byte userid of the new user, or any byte if not VACK
Login:
Client sends:
First byte l or L
Rest encoded with base32:
1 byte userid
16 bytes MD5 hash of: (first 32 bytes of password) xor (8 repetitions of login challenge)
CMC
Server replies:
LNAK means not accepted
x.x.x.x-y.y.y.y-mtu-netmask means accepted (server ip, client ip, mtu, netmask bits)
IP Request:
Client sends:
First byte i or I
5 bits coded as Base32 char, meaning userid
CMC
Server replies
BADIP if bad userid, or
I and then 4 bytes network order external IP address of iodined server
Case check:
Client sends:
First byte z or Z
Lots of data that should not be decoded
Server replies:
The requested domain copied raw
Switch codec:
Client sends:
First byte s or S
5 bits coded as Base32 char, meaning userid
5 bits coded as Base32 char, with value 5 or 6, representing number of raw
bits per encoded byte
Server sends:
Name of codec if accepted. After this all upstream data packets must
be encoded with the new codec.
BADCODEC if not accepted. Client must then revert to Base32
Probe downstream fragment size:
Client sends:
First byte r or R
15 bits coded as 3 Base32 chars: UUUUF FFFFF FFFFF
meaning 4 bits userid, 11 bits fragment size
Then follows a long random query which contents does not matter
Server sends:
Requested number of bytes as a response. The first two bytes contains
the requested length. Rest of message can be any data.
BADFRAG if requested length not accepted.
Set downstream fragment size:
Client sends:
First byte n or N
Rest encoded with base32:
1 byte userid
2 bytes new downstream fragment size
CMC
Server sends:
2 bytes new downstream fragment size. After this all downstream
payloads will be max (fragsize + 2) bytes long.
BADFRAG if not accepted.
Data:
Upstream data header:
3210 432 10 43 210 4321 0
+----+---+--+--+---+----+-+
|UUUU|SSS|FF|FF|DDD|GGGG|L|
+----+---+--+--+---+----+-+
Downstream data header:
7 654 3210 765 4321 0
+-+---+----+---+----+-+
|C|SSS|FFFF|DDD|GGGG|L|
+-+---+----+---+----+-+
UUUU = Userid
L = Last fragment in packet flag
SS = Upstream packet sequence number
FFFF = Upstream fragment number
DDD = Downstream packet sequence number
GGGG = Downstream fragment number
C = Compression enabled for downstream packet
Upstream data packet starts with 1 byte ASCII hex coded user byte, then 3 bytes
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
compressed.
Ping:
Client sends:
First byte p or P
Rest encoded with Base32:
1 byte with 4 bits userid
1 byte with:
3 bits downstream seqno
4 bits downstream fragment
CMC
The server response to Ping and Data packets is a DNS NULL type response:
If server has nothing to send, data length is 0 bytes.
If server has something to send, it will send a downstream data packet,
prefixed with 2 bytes header as shown above.

View File

@ -389,6 +389,33 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
} }
} }
return; return;
} else if(in[0] == 'I' || in[0] == 'i') {
/* Request for IP number */
in_addr_t replyaddr;
unsigned addr;
char reply[5];
userid = b32_8to5(in[1]);
if (check_user_and_ip(userid, q) != 0) {
write_dns(dns_fd, q, "BADIP", 5);
return; /* illegal id */
}
if (ns_ip != INADDR_ANY) {
/* If set, use assigned external ip (-n option) */
replyaddr = ns_ip;
} else {
/* otherwise return destination ip from packet */
memcpy(&replyaddr, &q->destination.s_addr, sizeof(in_addr_t));
}
addr = htonl(replyaddr);
reply[0] = 'I';
reply[1] = (addr >> 24) & 0xFF;
reply[2] = (addr >> 16) & 0xFF;
reply[3] = (addr >> 8) & 0xFF;
reply[4] = (addr >> 0) & 0xFF;
write_dns(dns_fd, q, reply, sizeof(reply));
} 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 */
@ -600,6 +627,8 @@ handle_ns_request(int dns_fd, struct query *q)
int len; int len;
if (ns_ip != INADDR_ANY) { if (ns_ip != INADDR_ANY) {
/* If ns_ip set, overwrite destination addr with it.
* Destination addr will be sent as additional record (A, IN) */
memcpy(&q->destination.s_addr, &ns_ip, sizeof(in_addr_t)); memcpy(&q->destination.s_addr, &ns_ip, sizeof(in_addr_t));
} }

View File

@ -19,7 +19,7 @@
/* This is the version of the network protocol /* This is the version of the network protocol
It is usually equal to the latest iodine version number */ It is usually equal to the latest iodine version number */
#define VERSION 0x00000500 #define VERSION 0x00000501
#endif /* _VERSION_H_ */ #endif /* _VERSION_H_ */