mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-25 02:55:15 +00:00
Fixed raw UDP mode + improved debugging
This commit is contained in:
parent
c633173fea
commit
3bcfe91769
97
src/client.c
97
src/client.c
@ -1123,14 +1123,7 @@ tunnel_tun(int tun_fd, int dns_fd)
|
||||
if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0)
|
||||
return -1;
|
||||
|
||||
/* Check if outgoing buffer can hold data */
|
||||
if (window_buffer_available(outbuf) < (read / MAX_FRAGSIZE) + 1) {
|
||||
DEBUG(1, " Outgoing buffer full (%lu/%lu), not adding data!",
|
||||
outbuf->numitems, outbuf->length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG(2, " IN: %lu bytes on tunnel, compression %d", read, compression_up);
|
||||
DEBUG(2, " IN: %lu bytes on tunnel, to be compressed: %d", read, compression_up);
|
||||
|
||||
if (conn != CONN_DNS_NULL || compression_up) {
|
||||
datalen = sizeof(out);
|
||||
@ -1142,6 +1135,13 @@ tunnel_tun(int tun_fd, int dns_fd)
|
||||
}
|
||||
|
||||
if (conn == CONN_DNS_NULL) {
|
||||
/* Check if outgoing buffer can hold data */
|
||||
if (window_buffer_available(outbuf) < (read / MAX_FRAGSIZE) + 1) {
|
||||
DEBUG(1, " Outgoing buffer full (%lu/%lu), not adding data!",
|
||||
outbuf->numitems, outbuf->length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
window_add_outgoing_data(outbuf, data, datalen, compression_up);
|
||||
/* Don't send anything here to respect min. send interval */
|
||||
} else {
|
||||
@ -1353,40 +1353,43 @@ client_tunnel(int tun_fd, int dns_fd)
|
||||
|
||||
/* TODO: detect DNS servers which drop frequent requests
|
||||
* TODO: adjust number of pending queries based on current data rate */
|
||||
sending = window_sending(outbuf);
|
||||
total = sending;
|
||||
check_pending_queries();
|
||||
if (num_pending < windowsize_down && lazymode)
|
||||
total = MAX(total, windowsize_down - num_pending);
|
||||
else if (num_pending < 1 && !lazymode)
|
||||
total = MAX(total, 1);
|
||||
if (conn == CONN_DNS_NULL) {
|
||||
sending = window_sending(outbuf);
|
||||
total = sending;
|
||||
check_pending_queries();
|
||||
if (num_pending < windowsize_down && lazymode)
|
||||
total = MAX(total, windowsize_down - num_pending);
|
||||
else if (num_pending < 1 && !lazymode)
|
||||
total = MAX(total, 1);
|
||||
|
||||
if (sending > 0 || total > 0 || next_downstream_ack >= 0) {
|
||||
if (sending > 0 || total > 0 || next_downstream_ack >= 0) {
|
||||
|
||||
/* Upstream traffic - this is where all ping/data queries are sent */
|
||||
if (sending > 0) {
|
||||
/* More to send - next fragment */
|
||||
send_next_frag(dns_fd);
|
||||
} else {
|
||||
/* Send ping if we didn't send anything yet */
|
||||
send_ping(dns_fd, 0, next_downstream_ack, (num_pings > 20 && num_pings % 50 == 0));
|
||||
next_downstream_ack = -1;
|
||||
/* Upstream traffic - this is where all ping/data queries are sent */
|
||||
if (sending > 0) {
|
||||
/* More to send - next fragment */
|
||||
send_next_frag(dns_fd);
|
||||
} else {
|
||||
/* Send ping if we didn't send anything yet */
|
||||
send_ping(dns_fd, 0, next_downstream_ack, (num_pings > 20 && num_pings % 50 == 0));
|
||||
next_downstream_ack = -1;
|
||||
}
|
||||
|
||||
sending--;
|
||||
total--;
|
||||
QTRACK_DEBUG(3, "Sent a query to fill server lazy buffer to %lu, will send another %d",
|
||||
lazymode ? windowsize_down : 1, total);
|
||||
|
||||
if (sending > 0 || (total > 0 && lazymode)) {
|
||||
/* TODO: enforce min send interval even if we get new data */
|
||||
tv = ms_to_timeval(min_send_interval_ms);
|
||||
tv.tv_usec += 1;
|
||||
} else if (total > 0 && !lazymode) {
|
||||
/* use immediate mode send interval if nothing pending */
|
||||
tv = ms_to_timeval(send_interval_ms);
|
||||
}
|
||||
|
||||
send_ping_soon = 0;
|
||||
}
|
||||
|
||||
sending--;
|
||||
total--;
|
||||
QTRACK_DEBUG(3, "Sent a query to fill server lazy buffer to %lu, will send another %d",
|
||||
lazymode ? windowsize_down : 1, total);
|
||||
|
||||
if (sending > 0 || (total > 0 && lazymode)) {
|
||||
tv = ms_to_timeval(min_send_interval_ms);
|
||||
tv.tv_usec += 1;
|
||||
} else if (total > 0 && !lazymode) {
|
||||
/* use immediate mode send interval if nothing pending */
|
||||
tv = ms_to_timeval(send_interval_ms);
|
||||
}
|
||||
|
||||
send_ping_soon = 0;
|
||||
}
|
||||
|
||||
if (stats) {
|
||||
@ -1404,11 +1407,12 @@ client_tunnel(int tun_fd, int dns_fd)
|
||||
min_send_interval_ms, rtt_total_ms / num_immediate, server_timeout_ms);
|
||||
fprintf(stderr, " Queries immediate: %5lu, timed out: %4lu target: %4ld ms\n",
|
||||
num_immediate, num_timeouts, max_timeout_ms);
|
||||
fprintf(stderr, " Frags resent: %4u, OOS: %4u down frag: %4ld ms\n",
|
||||
outbuf->resends, inbuf->oos, downstream_timeout_ms);
|
||||
fprintf(stderr, " TX fragments: %8lu" ", RX: %8lu" ", pings: %8lu" "\n\n",
|
||||
num_frags_sent, num_frags_recv, num_pings);
|
||||
|
||||
if (conn == CONN_DNS_NULL) {
|
||||
fprintf(stderr, " Frags resent: %4u, OOS: %4u down frag: %4ld ms\n",
|
||||
outbuf->resends, inbuf->oos, downstream_timeout_ms);
|
||||
fprintf(stderr, " TX fragments: %8lu" ", RX: %8lu" ", pings: %8lu" "\n\n",
|
||||
num_frags_sent, num_frags_recv, num_pings);
|
||||
}
|
||||
/* update since-last-report stats */
|
||||
sent_since_report = num_sent;
|
||||
recv_since_report = num_recv;
|
||||
@ -1420,11 +1424,12 @@ client_tunnel(int tun_fd, int dns_fd)
|
||||
if (send_ping_soon) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = send_ping_soon * 1000;
|
||||
send_ping_soon = 0;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
if (window_buffer_available(outbuf) > 16) {
|
||||
/* Fill up outgoing buffer with available data
|
||||
if (conn != CONN_DNS_NULL || window_buffer_available(outbuf) > 16) {
|
||||
/* Fill up outgoing buffer with available data if it has enough space
|
||||
* The windowing protocol manages data retransmits, timeouts etc. */
|
||||
FD_SET(tun_fd, &fds);
|
||||
}
|
||||
|
43
src/server.c
43
src/server.c
@ -853,14 +853,18 @@ handle_raw_login(uint8_t *packet, size_t len, struct query *q, int fd, int useri
|
||||
{
|
||||
char myhash[16];
|
||||
|
||||
if (len < 16) return;
|
||||
if (len < 16) {
|
||||
DEBUG(2, "Invalid raw login packet: length %lu < 16 bytes!", len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* can't use check_authenticated_user_and_ip() since IP address will be different,
|
||||
so duplicate here except IP address */
|
||||
if (userid < 0 || userid >= created_users) return;
|
||||
if (!check_authenticated_user_and_ip(userid, q)) return;
|
||||
if (userid < 0 || userid >= created_users ||
|
||||
check_authenticated_user_and_ip(userid, q) != 0) {
|
||||
DEBUG(2, "User %d not authenticated, ignoring raw login!", userid);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(1, "IN login raw, len %lu, from user %d", len, userid);
|
||||
DEBUG(1, "RX-raw: login, len %lu, from user %d", len, userid);
|
||||
|
||||
/* User sends hash of seed + 1 */
|
||||
login_calculate(myhash, 16, password, users[userid].seed + 1);
|
||||
@ -892,9 +896,9 @@ handle_raw_data(uint8_t *packet, size_t len, struct query *q, struct dnsfd *dns_
|
||||
/* Update time info for user */
|
||||
users[userid].last_pkt = time(NULL);
|
||||
|
||||
/* copy to packet buffer, update length TODO fix the raw UDP protocol */
|
||||
/* copy to packet buffer, update length */
|
||||
|
||||
DEBUG(3, "IN pkt raw, total %lu, from user %d", len, userid);
|
||||
DEBUG(3, "RX-raw: full pkt raw, length %lu, from user %d", len, userid);
|
||||
|
||||
handle_full_packet(tun_fd, dns_fds, userid, packet, len, 1);
|
||||
}
|
||||
@ -910,7 +914,7 @@ handle_raw_ping(struct query *q, int dns_fd, int userid)
|
||||
/* Update time info for user */
|
||||
users[userid].last_pkt = time(NULL);
|
||||
|
||||
DEBUG(3, "IN ping raw, from user %d", userid);
|
||||
DEBUG(3, "RX-raw: ping from user %d", userid);
|
||||
|
||||
/* Send ping reply */
|
||||
send_raw(dns_fd, NULL, 0, userid, RAW_HDR_CMD_PING, &q->from, q->fromlen);
|
||||
@ -920,30 +924,37 @@ static int
|
||||
raw_decode(uint8_t *packet, size_t len, struct query *q, int dns_fd, struct dnsfd *dns_fds, int tun_fd)
|
||||
{
|
||||
int raw_user;
|
||||
uint8_t raw_cmd;
|
||||
|
||||
/* minimum length */
|
||||
if (len < RAW_HDR_LEN) return 0;
|
||||
/* 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;
|
||||
|
||||
raw_cmd = RAW_HDR_GET_CMD(packet);
|
||||
raw_user = RAW_HDR_GET_USR(packet);
|
||||
DEBUG(3, "TX-raw: client %s, user %d, raw command '%c' length %lu",
|
||||
format_addr(&q->from, q->fromlen), raw_user, RAW_HDR_GET_CMD(packet), len);
|
||||
switch (RAW_HDR_GET_CMD(packet)) {
|
||||
|
||||
DEBUG(3, "RX-raw: client %s, user %d, raw command 0x%02X, length %lu",
|
||||
format_addr(&q->from, q->fromlen), raw_user, raw_cmd, len);
|
||||
|
||||
packet += RAW_HDR_LEN;
|
||||
len -= RAW_HDR_LEN;
|
||||
switch (raw_cmd) {
|
||||
case RAW_HDR_CMD_LOGIN:
|
||||
/* Login challenge */
|
||||
handle_raw_login(&packet[RAW_HDR_LEN], len - RAW_HDR_LEN, q, dns_fd, raw_user);
|
||||
handle_raw_login(packet, 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_fds, tun_fd, raw_user);
|
||||
handle_raw_data(packet, len, q, dns_fds, tun_fd, raw_user);
|
||||
break;
|
||||
case RAW_HDR_CMD_PING:
|
||||
/* Keepalive packet */
|
||||
handle_raw_ping(q, dns_fd, raw_user);
|
||||
break;
|
||||
default:
|
||||
DEBUG(1, "Unhandled raw command %02X from user %d", RAW_HDR_GET_CMD(packet), raw_user);
|
||||
DEBUG(1, "Unhandled raw command %02X from user %d", raw_cmd, raw_user);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user