mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-26 23:16:05 +03:00
#36, upstream traffic now sent in raw mode
This commit is contained in:
parent
e2c8ac3985
commit
5d3b502ec6
15
src/common.h
15
src/common.h
@ -21,8 +21,13 @@
|
|||||||
#define RAW_HDR_LEN 4
|
#define RAW_HDR_LEN 4
|
||||||
#define RAW_HDR_IDENT_LEN 3
|
#define RAW_HDR_IDENT_LEN 3
|
||||||
#define RAW_HDR_CMD 3
|
#define RAW_HDR_CMD 3
|
||||||
#define RAW_HDR_CMD_LOGIN 0x01
|
#define RAW_HDR_CMD_LOGIN 0x10
|
||||||
#define RAW_HDR_CMD_DATA 0x02
|
#define RAW_HDR_CMD_DATA 0x20
|
||||||
|
|
||||||
|
#define RAW_HDR_CMD_MASK 0xF0
|
||||||
|
#define RAW_HDR_USR_MASK 0x0F
|
||||||
|
#define RAW_HDR_GET_CMD(x) ((x)[RAW_HDR_CMD] & RAW_HDR_CMD_MASK)
|
||||||
|
#define RAW_HDR_GET_USR(x) ((x)[RAW_HDR_CMD] & RAW_HDR_USR_MASK)
|
||||||
extern const unsigned char raw_header[RAW_HDR_LEN];
|
extern const unsigned char raw_header[RAW_HDR_LEN];
|
||||||
|
|
||||||
#ifdef WINDOWS32
|
#ifdef WINDOWS32
|
||||||
@ -85,6 +90,12 @@ struct query {
|
|||||||
int fromlen;
|
int fromlen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum connection {
|
||||||
|
CONN_RAW_UDP,
|
||||||
|
CONN_DNS_NULL,
|
||||||
|
CONN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
void check_superuser(void (*usage_fn)(void));
|
void check_superuser(void (*usage_fn)(void));
|
||||||
int open_dns(int, in_addr_t);
|
int open_dns(int, in_addr_t);
|
||||||
void close_dns(int);
|
void close_dns(int);
|
||||||
|
77
src/iodine.c
77
src/iodine.c
@ -60,6 +60,7 @@ WSADATA wsa_data;
|
|||||||
|
|
||||||
static void send_ping(int fd);
|
static void send_ping(int fd);
|
||||||
static void send_chunk(int fd);
|
static void send_chunk(int fd);
|
||||||
|
static void send_raw_data(int fd);
|
||||||
static int build_hostname(char *buf, size_t buflen,
|
static int build_hostname(char *buf, size_t buflen,
|
||||||
const char *data, const size_t datalen,
|
const char *data, const size_t datalen,
|
||||||
const char *topdomain, struct encoder *encoder);
|
const char *topdomain, struct encoder *encoder);
|
||||||
@ -94,6 +95,9 @@ static struct encoder *b32;
|
|||||||
* Defaults to Base32, can be changed after handshake */
|
* Defaults to Base32, can be changed after handshake */
|
||||||
static struct encoder *dataenc;
|
static struct encoder *dataenc;
|
||||||
|
|
||||||
|
/* My connection mode */
|
||||||
|
static enum connection conn;
|
||||||
|
|
||||||
#if !defined(BSD) && !defined(__GLIBC__)
|
#if !defined(BSD) && !defined(__GLIBC__)
|
||||||
static char *__progname;
|
static char *__progname;
|
||||||
#endif
|
#endif
|
||||||
@ -120,7 +124,7 @@ send_query(int fd, char *hostname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_raw(int fd, char *buf, int buflen, int cmd)
|
send_raw(int fd, char *buf, int buflen, int user, int cmd)
|
||||||
{
|
{
|
||||||
char packet[4096];
|
char packet[4096];
|
||||||
int len;
|
int len;
|
||||||
@ -131,7 +135,7 @@ send_raw(int fd, char *buf, int buflen, int cmd)
|
|||||||
memcpy(&packet[RAW_HDR_LEN], buf, len);
|
memcpy(&packet[RAW_HDR_LEN], buf, len);
|
||||||
|
|
||||||
len += RAW_HDR_LEN;
|
len += RAW_HDR_LEN;
|
||||||
packet[RAW_HDR_CMD] = cmd;
|
packet[RAW_HDR_CMD] = cmd | (user & 0x0F);
|
||||||
|
|
||||||
sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv));
|
sendto(fd, packet, len, 0, (struct sockaddr*)&raw_serv, sizeof(raw_serv));
|
||||||
}
|
}
|
||||||
@ -263,7 +267,11 @@ tunnel_tun(int tun_fd, int dns_fd)
|
|||||||
outpkt.seqno++;
|
outpkt.seqno++;
|
||||||
outpkt.fragment = 0;
|
outpkt.fragment = 0;
|
||||||
|
|
||||||
send_chunk(dns_fd);
|
if (conn == CONN_DNS_NULL) {
|
||||||
|
send_chunk(dns_fd);
|
||||||
|
} else {
|
||||||
|
send_raw_data(dns_fd);
|
||||||
|
}
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
@ -327,7 +335,7 @@ tunnel(int tun_fd, int dns_fd)
|
|||||||
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
if (!is_sending()) {
|
if ((!is_sending()) || conn == CONN_RAW_UDP) {
|
||||||
FD_SET(tun_fd, &fds);
|
FD_SET(tun_fd, &fds);
|
||||||
}
|
}
|
||||||
FD_SET(dns_fd, &fds);
|
FD_SET(dns_fd, &fds);
|
||||||
@ -340,7 +348,7 @@ tunnel(int tun_fd, int dns_fd)
|
|||||||
if (i < 0)
|
if (i < 0)
|
||||||
err(1, "select");
|
err(1, "select");
|
||||||
|
|
||||||
if (i == 0) /* timeout */
|
if (i == 0 && conn == CONN_DNS_NULL) /* timeout */
|
||||||
send_ping(dns_fd);
|
send_ping(dns_fd);
|
||||||
else {
|
else {
|
||||||
if (FD_ISSET(tun_fd, &fds)) {
|
if (FD_ISSET(tun_fd, &fds)) {
|
||||||
@ -357,6 +365,12 @@ tunnel(int tun_fd, int dns_fd)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_raw_data(int dns_fd)
|
||||||
|
{
|
||||||
|
send_raw(dns_fd, outpkt.data, outpkt.len, userid, RAW_HDR_CMD_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_chunk(int fd)
|
send_chunk(int fd)
|
||||||
{
|
{
|
||||||
@ -507,11 +521,10 @@ send_ip_request(int fd, int userid)
|
|||||||
static void
|
static void
|
||||||
send_raw_udp_login(int dns_fd, int userid, int seed)
|
send_raw_udp_login(int dns_fd, int userid, int seed)
|
||||||
{
|
{
|
||||||
char buf[17];
|
char buf[16];
|
||||||
login_calculate(buf, 16, password, seed + 1);
|
login_calculate(buf, 16, password, seed + 1);
|
||||||
buf[16] = userid;
|
|
||||||
|
|
||||||
send_raw(dns_fd, buf, sizeof(buf), RAW_HDR_CMD_LOGIN);
|
send_raw(dns_fd, buf, sizeof(buf), userid, RAW_HDR_CMD_LOGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -715,7 +728,7 @@ handshake_raw_udp(int dns_fd, int seed)
|
|||||||
|
|
||||||
if (!remoteaddr) {
|
if (!remoteaddr) {
|
||||||
fprintf(stderr, " failed to get IP.\n");
|
fprintf(stderr, " failed to get IP.\n");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
fprintf(stderr, " at %s: ", inet_ntoa(server));
|
fprintf(stderr, " at %s: ", inet_ntoa(server));
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
@ -743,16 +756,15 @@ handshake_raw_udp(int dns_fd, int seed)
|
|||||||
if(r > 0) {
|
if(r > 0) {
|
||||||
/* recv() needed for windows, dont change to read() */
|
/* recv() needed for windows, dont change to read() */
|
||||||
len = recv(dns_fd, in, sizeof(in), 0);
|
len = recv(dns_fd, in, sizeof(in), 0);
|
||||||
if (len >= (17 + RAW_HDR_LEN)) {
|
if (len >= (16 + RAW_HDR_LEN)) {
|
||||||
char hash[16];
|
char hash[16];
|
||||||
login_calculate(hash, 16, password, seed - 1);
|
login_calculate(hash, 16, password, seed - 1);
|
||||||
if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0
|
if (memcmp(in, raw_header, RAW_HDR_IDENT_LEN) == 0
|
||||||
&& in[RAW_HDR_CMD] == RAW_HDR_CMD_LOGIN
|
&& RAW_HDR_GET_CMD(in) == RAW_HDR_CMD_LOGIN
|
||||||
&& memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0
|
&& memcmp(&in[RAW_HDR_LEN], hash, sizeof(hash)) == 0) {
|
||||||
&& in[16 + RAW_HDR_LEN] == userid) {
|
|
||||||
|
|
||||||
fprintf(stderr, "OK\n");
|
fprintf(stderr, "OK\n");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -761,7 +773,7 @@ handshake_raw_udp(int dns_fd, int seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "failed\n");
|
fprintf(stderr, "failed\n");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1016,22 +1028,24 @@ handshake(int dns_fd, int autodetect_frag_size, int fragsize)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
handshake_raw_udp(dns_fd, seed);
|
if (handshake_raw_udp(dns_fd, seed)) {
|
||||||
|
conn = CONN_RAW_UDP;
|
||||||
|
} else {
|
||||||
|
case_preserved = handshake_case_check(dns_fd);
|
||||||
|
|
||||||
case_preserved = handshake_case_check(dns_fd);
|
if (case_preserved) {
|
||||||
|
handshake_switch_codec(dns_fd);
|
||||||
if (case_preserved) {
|
|
||||||
handshake_switch_codec(dns_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (autodetect_frag_size) {
|
|
||||||
fragsize = handshake_autoprobe_fragsize(dns_fd);
|
|
||||||
if (!fragsize) {
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
handshake_set_fragsize(dns_fd, fragsize);
|
if (autodetect_frag_size) {
|
||||||
|
fragsize = handshake_autoprobe_fragsize(dns_fd);
|
||||||
|
if (!fragsize) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handshake_set_fragsize(dns_fd, fragsize);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1178,6 +1192,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
b32 = get_base32_encoder();
|
b32 = get_base32_encoder();
|
||||||
dataenc = get_base32_encoder();
|
dataenc = get_base32_encoder();
|
||||||
|
conn = CONN_DNS_NULL;
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
||||||
@ -1312,7 +1327,11 @@ main(int argc, char **argv)
|
|||||||
goto cleanup2;
|
goto cleanup2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr);
|
if (conn == CONN_DNS_NULL) {
|
||||||
|
fprintf(stderr, "Sending queries for %s to %s\n", topdomain, nameserv_addr);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Sending raw traffic directly to %s\n", inet_ntoa(raw_serv.sin_addr));
|
||||||
|
}
|
||||||
|
|
||||||
if (foreground == 0)
|
if (foreground == 0)
|
||||||
do_detach();
|
do_detach();
|
||||||
|
153
src/iodined.c
153
src/iodined.c
@ -85,8 +85,9 @@ static int debug;
|
|||||||
static char *__progname;
|
static char *__progname;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int read_dns(int, struct query *);
|
static int read_dns(int, int, struct query *);
|
||||||
static void write_dns(int, struct query *, char *, int);
|
static void write_dns(int, struct query *, char *, int);
|
||||||
|
static void handle_full_packet(int, int);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sigint(int sig)
|
sigint(int sig)
|
||||||
@ -295,15 +296,12 @@ 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)
|
||||||
{
|
{
|
||||||
struct in_addr tempip;
|
struct in_addr tempip;
|
||||||
struct ip *hdr;
|
|
||||||
unsigned long outlen;
|
|
||||||
char in[512];
|
char in[512];
|
||||||
char logindata[16];
|
char logindata[16];
|
||||||
char out[64*1024];
|
char out[64*1024];
|
||||||
char unpacked[64*1024];
|
char unpacked[64*1024];
|
||||||
char *tmp[2];
|
char *tmp[2];
|
||||||
int userid;
|
int userid;
|
||||||
int touser;
|
|
||||||
int version;
|
int version;
|
||||||
int code;
|
int code;
|
||||||
int read;
|
int read;
|
||||||
@ -589,30 +587,7 @@ handle_null_request(int tun_fd, int dns_fd, struct query *q, int domain_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastfrag & 1) { /* packet is complete */
|
if (lastfrag & 1) { /* packet is complete */
|
||||||
int ret;
|
handle_full_packet(tun_fd, userid);
|
||||||
outlen = sizeof(out);
|
|
||||||
ret = uncompress((uint8_t*)out, &outlen,
|
|
||||||
(uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len);
|
|
||||||
|
|
||||||
if (ret == Z_OK) {
|
|
||||||
hdr = (struct ip*) (out + 4);
|
|
||||||
touser = find_user_by_ip(hdr->ip_dst.s_addr);
|
|
||||||
|
|
||||||
if (touser == -1) {
|
|
||||||
/* send the uncompressed packet to tun device */
|
|
||||||
write_tun(tun_fd, out, outlen);
|
|
||||||
} else {
|
|
||||||
/* send the compressed packet to other client
|
|
||||||
* if another packet is queued, throw away this one. TODO build queue */
|
|
||||||
if (users[touser].outpacket.len == 0) {
|
|
||||||
memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len);
|
|
||||||
users[touser].outpacket.len = users[userid].inpacket.len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Discarded data, uncompress() result: %d\n", ret);
|
|
||||||
}
|
|
||||||
users[userid].inpacket.len = users[userid].inpacket.offset = 0;
|
|
||||||
}
|
}
|
||||||
/* Update seqno and maybe send immediate response packet */
|
/* Update seqno and maybe send immediate response packet */
|
||||||
update_downstream_seqno(dns_fd, userid, dn_seq, dn_frag);
|
update_downstream_seqno(dns_fd, userid, dn_seq, dn_frag);
|
||||||
@ -730,7 +705,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd)
|
|||||||
int domain_len;
|
int domain_len;
|
||||||
int inside_topdomain;
|
int inside_topdomain;
|
||||||
|
|
||||||
if ((read = read_dns(dns_fd, &q)) <= 0)
|
if ((read = read_dns(dns_fd, tun_fd, &q)) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (debug >= 2) {
|
if (debug >= 2) {
|
||||||
@ -820,15 +795,15 @@ tunnel(int tun_fd, int dns_fd, int bind_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(FD_ISSET(tun_fd, &fds)) {
|
if (FD_ISSET(tun_fd, &fds)) {
|
||||||
tunnel_tun(tun_fd, dns_fd);
|
tunnel_tun(tun_fd, dns_fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(FD_ISSET(dns_fd, &fds)) {
|
if (FD_ISSET(dns_fd, &fds)) {
|
||||||
tunnel_dns(tun_fd, dns_fd, bind_fd);
|
tunnel_dns(tun_fd, dns_fd, bind_fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(FD_ISSET(bind_fd, &fds)) {
|
if (FD_ISSET(bind_fd, &fds)) {
|
||||||
tunnel_bind(bind_fd, dns_fd);
|
tunnel_bind(bind_fd, dns_fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -839,7 +814,42 @@ tunnel(int tun_fd, int dns_fd, int bind_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_raw(int fd, char *buf, int buflen, int cmd, struct query *q)
|
handle_full_packet(int tun_fd, int userid)
|
||||||
|
{
|
||||||
|
unsigned long outlen;
|
||||||
|
char out[64*1024];
|
||||||
|
int touser;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
outlen = sizeof(out);
|
||||||
|
ret = uncompress((uint8_t*)out, &outlen,
|
||||||
|
(uint8_t*)users[userid].inpacket.data, users[userid].inpacket.len);
|
||||||
|
|
||||||
|
if (ret == Z_OK) {
|
||||||
|
struct ip *hdr;
|
||||||
|
|
||||||
|
hdr = (struct ip*) (out + 4);
|
||||||
|
touser = find_user_by_ip(hdr->ip_dst.s_addr);
|
||||||
|
|
||||||
|
if (touser == -1) {
|
||||||
|
/* send the uncompressed packet to tun device */
|
||||||
|
write_tun(tun_fd, out, outlen);
|
||||||
|
} else {
|
||||||
|
/* send the compressed packet to other client
|
||||||
|
* if another packet is queued, throw away this one. TODO build queue */
|
||||||
|
if (users[touser].outpacket.len == 0) {
|
||||||
|
memcpy(users[touser].outpacket.data, users[userid].inpacket.data, users[userid].inpacket.len);
|
||||||
|
users[touser].outpacket.len = users[userid].inpacket.len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Discarded data, uncompress() result: %d\n", ret);
|
||||||
|
}
|
||||||
|
users[userid].inpacket.len = users[userid].inpacket.offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_raw(int fd, char *buf, int buflen, int user, int cmd, struct query *q)
|
||||||
{
|
{
|
||||||
char packet[4096];
|
char packet[4096];
|
||||||
int len;
|
int len;
|
||||||
@ -850,51 +860,96 @@ send_raw(int fd, char *buf, int buflen, int cmd, struct query *q)
|
|||||||
memcpy(&packet[RAW_HDR_LEN], buf, len);
|
memcpy(&packet[RAW_HDR_LEN], buf, len);
|
||||||
|
|
||||||
len += RAW_HDR_LEN;
|
len += RAW_HDR_LEN;
|
||||||
packet[RAW_HDR_CMD] = cmd;
|
packet[RAW_HDR_CMD] = cmd | (user & 0x0F);
|
||||||
|
|
||||||
sendto(fd, packet, len, 0, &q->from, q->fromlen);
|
sendto(fd, packet, len, 0, &q->from, q->fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_raw_login(char *packet, int len, struct query *q, int fd)
|
handle_raw_login(char *packet, int len, struct query *q, int fd, int userid)
|
||||||
{
|
{
|
||||||
int userid;
|
|
||||||
char myhash[16];
|
char myhash[16];
|
||||||
|
|
||||||
if (len < 17) return;
|
if (len < 16) return;
|
||||||
|
|
||||||
userid = packet[16];
|
|
||||||
if (userid < 0 || userid > created_users) return;
|
if (userid < 0 || userid > created_users) return;
|
||||||
if (!users[userid].active) return;
|
if (!users[userid].active) return;
|
||||||
|
|
||||||
|
/* User sends hash of seed + 1 */
|
||||||
login_calculate(myhash, 16, password, users[userid].seed + 1);
|
login_calculate(myhash, 16, password, users[userid].seed + 1);
|
||||||
if (memcmp(packet, myhash, 16) == 0) {
|
if (memcmp(packet, myhash, 16) == 0) {
|
||||||
|
struct sockaddr_in *tempin;
|
||||||
|
|
||||||
|
/* Update query and time info for user */
|
||||||
|
users[userid].last_pkt = time(NULL);
|
||||||
|
memcpy(&(users[userid].q), q, sizeof(struct query));
|
||||||
|
|
||||||
|
/* Store remote IP number */
|
||||||
|
tempin = (struct sockaddr_in *) &(q->from);
|
||||||
|
memcpy(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr));
|
||||||
|
|
||||||
/* Correct hash, reply with hash of seed - 1 */
|
/* Correct hash, reply with hash of seed - 1 */
|
||||||
|
user_set_conn_type(userid, CONN_RAW_UDP);
|
||||||
users[userid].last_pkt = time(NULL);
|
users[userid].last_pkt = time(NULL);
|
||||||
login_calculate(myhash, 16, password, users[userid].seed - 1);
|
login_calculate(myhash, 16, password, users[userid].seed - 1);
|
||||||
memcpy(packet, myhash, 16);
|
send_raw(fd, myhash, 16, userid, RAW_HDR_CMD_LOGIN, q);
|
||||||
send_raw(fd, packet, 17, RAW_HDR_CMD_LOGIN, q);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
raw_decode(char *packet, int len, struct query *q, int fd)
|
handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, int userid)
|
||||||
{
|
{
|
||||||
|
if (check_user_and_ip(userid, q) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update query and time info for user */
|
||||||
|
users[userid].last_pkt = time(NULL);
|
||||||
|
memcpy(&(users[userid].q), q, sizeof(struct query));
|
||||||
|
|
||||||
|
/* copy to packet buffer, update length */
|
||||||
|
users[userid].inpacket.offset = 0;
|
||||||
|
memcpy(users[userid].inpacket.data, packet, len);
|
||||||
|
users[userid].inpacket.len = len;
|
||||||
|
|
||||||
|
if (debug >= 1) {
|
||||||
|
fprintf(stderr, "IN pkt raw, total %d, from user %d\n",
|
||||||
|
users[userid].inpacket.len, userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_full_packet(tun_fd, userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
raw_decode(char *packet, int len, struct query *q, int dns_fd, int tun_fd)
|
||||||
|
{
|
||||||
|
int raw_user;
|
||||||
|
|
||||||
/* minimum length */
|
/* minimum length */
|
||||||
if (len < RAW_HDR_LEN) return 0;
|
if (len < RAW_HDR_LEN) return 0;
|
||||||
/* should start with header */
|
/* should start with header */
|
||||||
if (memcmp(packet, raw_header, RAW_HDR_IDENT_LEN)) return 0;
|
if (memcmp(packet, raw_header, RAW_HDR_IDENT_LEN)) return 0;
|
||||||
|
|
||||||
if (packet[RAW_HDR_CMD] == RAW_HDR_CMD_LOGIN) {
|
raw_user = RAW_HDR_GET_USR(packet);
|
||||||
handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, fd);
|
printf("raw %02x\n", packet[RAW_HDR_CMD]);
|
||||||
} else {
|
switch (RAW_HDR_GET_CMD(packet)) {
|
||||||
warnx("Unhandled raw command %02X\n", packet[RAW_HDR_CMD]);
|
case RAW_HDR_CMD_LOGIN:
|
||||||
|
/* Login challenge */
|
||||||
|
handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, raw_user);
|
||||||
|
break;
|
||||||
|
case RAW_HDR_CMD_DATA:
|
||||||
|
/* Data packet */
|
||||||
|
handle_raw_data(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, tun_fd, raw_user);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warnx("Unhandled raw command %02X from user %d", RAW_HDR_GET_CMD(packet), raw_user);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_dns(int fd, struct query *q)
|
read_dns(int fd, int tun_fd, struct query *q) /* FIXME: tun_fd is because of raw_decode() below */
|
||||||
{
|
{
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
@ -929,7 +984,7 @@ read_dns(int fd, struct query *q)
|
|||||||
q->fromlen = addrlen;
|
q->fromlen = addrlen;
|
||||||
|
|
||||||
/* TODO do not handle raw packets here! */
|
/* TODO do not handle raw packets here! */
|
||||||
if (raw_decode(packet, r, q, fd)) {
|
if (raw_decode(packet, r, q, fd, tun_fd)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (dns_decode(NULL, 0, q, QR_QUERY, packet, r) < 0) {
|
if (dns_decode(NULL, 0, q, QR_QUERY, packet, r) < 0) {
|
||||||
@ -1177,7 +1232,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
topdomain = strdup(argv[1]);
|
topdomain = strdup(argv[1]);
|
||||||
if(strlen(topdomain) <= 128) {
|
if (strlen(topdomain) <= 128) {
|
||||||
if(check_topdomain(topdomain)) {
|
if(check_topdomain(topdomain)) {
|
||||||
warnx("Topdomain contains invalid characters.");
|
warnx("Topdomain contains invalid characters.");
|
||||||
usage();
|
usage();
|
||||||
|
16
src/user.c
16
src/user.c
@ -90,6 +90,7 @@ init_users(in_addr_t my_ip, int netbits)
|
|||||||
users[i].out_acked_seqno = 0;
|
users[i].out_acked_seqno = 0;
|
||||||
users[i].out_acked_fragment = 0;
|
users[i].out_acked_fragment = 0;
|
||||||
users[i].fragsize = 4096;
|
users[i].fragsize = 4096;
|
||||||
|
users[i].conn = CONN_DNS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return created_users;
|
return created_users;
|
||||||
@ -161,6 +162,8 @@ find_available_user()
|
|||||||
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) {
|
if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) {
|
||||||
users[i].active = 1;
|
users[i].active = 1;
|
||||||
users[i].last_pkt = time(NULL);
|
users[i].last_pkt = time(NULL);
|
||||||
|
users[i].fragsize = 4096;
|
||||||
|
users[i].conn = CONN_DNS_NULL;
|
||||||
ret = i;
|
ret = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -176,3 +179,16 @@ user_switch_codec(int userid, struct encoder *enc)
|
|||||||
|
|
||||||
users[userid].encoder = enc;
|
users[userid].encoder = enc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
user_set_conn_type(int userid, enum connection c)
|
||||||
|
{
|
||||||
|
if (userid < 0 || userid >= USERS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (c < 0 || c >= CONN_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
users[userid].conn = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ struct user {
|
|||||||
int out_acked_seqno;
|
int out_acked_seqno;
|
||||||
int out_acked_fragment;
|
int out_acked_fragment;
|
||||||
int fragsize;
|
int fragsize;
|
||||||
|
enum connection conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct user users[USERS];
|
extern struct user users[USERS];
|
||||||
@ -44,5 +45,6 @@ int find_user_by_ip(uint32_t);
|
|||||||
int all_users_waiting_to_send();
|
int all_users_waiting_to_send();
|
||||||
int find_available_user();
|
int find_available_user();
|
||||||
void user_switch_codec(int userid, struct encoder *enc);
|
void user_switch_codec(int userid, struct encoder *enc);
|
||||||
|
void user_set_conn_type(int userid, enum connection c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user