mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-25 11:05:15 +00:00
Added command line option presets (--preset or -Y)
Fixed some refactoring issues and passing this.* as arguments
This commit is contained in:
parent
f4d1d1634c
commit
7068bcc08d
282
src/client.c
282
src/client.c
@ -162,7 +162,7 @@ immediate_mode_defaults()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
update_server_timeout(int dns_fd, int handshake)
|
update_server_timeout(int handshake)
|
||||||
/* Calculate server timeout based on average RTT, send ping "handshake" to set
|
/* Calculate server timeout based on average RTT, send ping "handshake" to set
|
||||||
* if handshake sent, return query ID */
|
* if handshake sent, return query ID */
|
||||||
{
|
{
|
||||||
@ -201,7 +201,7 @@ update_server_timeout(int dns_fd, int handshake)
|
|||||||
|
|
||||||
if (handshake) {
|
if (handshake) {
|
||||||
/* Send ping handshake to set server timeout */
|
/* Send ping handshake to set server timeout */
|
||||||
return send_ping(dns_fd, 1, -1, 1);
|
return send_ping(1, -1, 1);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -309,7 +309,7 @@ got_response(int id, int immediate, int fail)
|
|||||||
this.num_immediate++;
|
this.num_immediate++;
|
||||||
|
|
||||||
if (this.autodetect_server_timeout)
|
if (this.autodetect_server_timeout)
|
||||||
update_server_timeout(-1, 0);
|
update_server_timeout(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove query info from buffer to mark it as answered */
|
/* Remove query info from buffer to mark it as answered */
|
||||||
@ -326,7 +326,7 @@ got_response(int id, int immediate, int fail)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
send_query(int fd, uint8_t *hostname)
|
send_query(uint8_t *hostname)
|
||||||
/* Returns DNS ID of sent query */
|
/* Returns DNS ID of sent query */
|
||||||
{
|
{
|
||||||
uint8_t packet[4096];
|
uint8_t packet[4096];
|
||||||
@ -351,7 +351,7 @@ send_query(int fd, uint8_t *hostname)
|
|||||||
|
|
||||||
DEBUG(4, " Sendquery: id %5d name[0] '%c'", q.id, hostname[0]);
|
DEBUG(4, " Sendquery: id %5d name[0] '%c'", q.id, hostname[0]);
|
||||||
|
|
||||||
sendto(fd, packet, len, 0, (struct sockaddr*) &this.nameserv_addrs[this.current_nameserver],
|
sendto(this.dns_fd, packet, len, 0, (struct sockaddr*) &this.nameserv_addrs[this.current_nameserver],
|
||||||
sizeof(struct sockaddr_storage));
|
sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
client_rotate_nameserver();
|
client_rotate_nameserver();
|
||||||
@ -391,14 +391,14 @@ send_query(int fd, uint8_t *hostname)
|
|||||||
this.lazymode = 0;
|
this.lazymode = 0;
|
||||||
this.server_timeout_ms = 0;
|
this.server_timeout_ms = 0;
|
||||||
}
|
}
|
||||||
update_server_timeout(fd, 1);
|
update_server_timeout(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return q.id;
|
return q.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_raw(int fd, uint8_t *buf, size_t buflen, int user, int cmd)
|
send_raw(uint8_t *buf, size_t buflen, int cmd)
|
||||||
{
|
{
|
||||||
char packet[4096];
|
char packet[4096];
|
||||||
int len;
|
int len;
|
||||||
@ -411,20 +411,20 @@ send_raw(int fd, uint8_t *buf, size_t buflen, int user, int cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
len += RAW_HDR_LEN;
|
len += RAW_HDR_LEN;
|
||||||
packet[RAW_HDR_CMD] = (cmd & 0xF0) | (user & 0x0F);
|
packet[RAW_HDR_CMD] = (cmd & 0xF0) | (this.userid & 0x0F);
|
||||||
|
|
||||||
sendto(fd, packet, len, 0, (struct sockaddr*)&this.raw_serv, sizeof(this.raw_serv));
|
sendto(this.dns_fd, packet, len, 0, (struct sockaddr*)&this.raw_serv, sizeof(this.raw_serv));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_raw_data(int dns_fd, uint8_t *data, size_t datalen)
|
send_raw_data(uint8_t *data, size_t datalen)
|
||||||
{
|
{
|
||||||
send_raw(dns_fd, data, datalen, this.userid, RAW_HDR_CMD_DATA);
|
send_raw(data, datalen, RAW_HDR_CMD_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
send_packet(int fd, char cmd, const uint8_t *data, const size_t datalen)
|
send_packet(char cmd, const uint8_t *data, const size_t datalen)
|
||||||
/* Base32 encodes data and sends as single DNS query
|
/* Base32 encodes data and sends as single DNS query
|
||||||
* Returns ID of sent query */
|
* Returns ID of sent query */
|
||||||
{
|
{
|
||||||
@ -434,11 +434,11 @@ send_packet(int fd, char cmd, const uint8_t *data, const size_t datalen)
|
|||||||
|
|
||||||
build_hostname(buf, sizeof(buf), data, datalen, this.topdomain, b32, this.hostname_maxlen, 1);
|
build_hostname(buf, sizeof(buf), data, datalen, this.topdomain, b32, this.hostname_maxlen, 1);
|
||||||
|
|
||||||
return send_query(fd, buf);
|
return send_query(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
send_ping(int fd, int ping_response, int ack, int set_timeout)
|
send_ping(int ping_response, int ack, int set_timeout)
|
||||||
{
|
{
|
||||||
this.num_pings++;
|
this.num_pings++;
|
||||||
if (this.conn == CONN_DNS_NULL) {
|
if (this.conn == CONN_DNS_NULL) {
|
||||||
@ -469,19 +469,19 @@ send_ping(int fd, int ping_response, int ack, int set_timeout)
|
|||||||
ping_response, ack, set_timeout ? "SET " : "", this.server_timeout_ms,
|
ping_response, ack, set_timeout ? "SET " : "", this.server_timeout_ms,
|
||||||
this.downstream_timeout_ms, data[8]);
|
this.downstream_timeout_ms, data[8]);
|
||||||
|
|
||||||
id = send_packet(fd, 'p', data, sizeof(data));
|
id = send_packet('p', data, sizeof(data));
|
||||||
|
|
||||||
/* Log query ID as being sent now */
|
/* Log query ID as being sent now */
|
||||||
query_sent_now(id);
|
query_sent_now(id);
|
||||||
return id;
|
return id;
|
||||||
} else {
|
} else {
|
||||||
send_raw(fd, NULL, 0, this.userid, RAW_HDR_CMD_PING);
|
send_raw(NULL, 0, RAW_HDR_CMD_PING);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_next_frag(int fd)
|
send_next_frag()
|
||||||
/* Sends next available fragment of data from the outgoing window buffer */
|
/* Sends next available fragment of data from the outgoing window buffer */
|
||||||
{
|
{
|
||||||
static uint8_t buf[MAX_FRAGSIZE], hdr[5];
|
static uint8_t buf[MAX_FRAGSIZE], hdr[5];
|
||||||
@ -497,7 +497,7 @@ send_next_frag(int fd)
|
|||||||
if (this.outbuf->numitems > 0) {
|
if (this.outbuf->numitems > 0) {
|
||||||
/* There is stuff to send but we're out of sync, so send a ping
|
/* There is stuff to send but we're out of sync, so send a ping
|
||||||
* to get things back in order and keep the packets flowing */
|
* to get things back in order and keep the packets flowing */
|
||||||
send_ping(fd, 1, this.next_downstream_ack, 1);
|
send_ping(1, this.next_downstream_ack, 1);
|
||||||
this.next_downstream_ack = -1;
|
this.next_downstream_ack = -1;
|
||||||
window_tick(this.outbuf);
|
window_tick(this.outbuf);
|
||||||
}
|
}
|
||||||
@ -532,7 +532,7 @@ send_next_frag(int fd)
|
|||||||
DEBUG(3, " SEND DATA: seq %d, ack %d, len %lu, s%d e%d c%d flags %1X",
|
DEBUG(3, " SEND DATA: seq %d, ack %d, len %lu, s%d e%d c%d flags %1X",
|
||||||
f->seqID, f->ack_other, f->len, f->start, f->end, f->compressed, hdr[2] >> 4);
|
f->seqID, f->ack_other, f->len, f->start, f->end, f->compressed, hdr[2] >> 4);
|
||||||
|
|
||||||
id = send_query(fd, buf);
|
id = send_query(buf);
|
||||||
/* Log query ID as being sent now */
|
/* Log query ID as being sent now */
|
||||||
query_sent_now(id);
|
query_sent_now(id);
|
||||||
|
|
||||||
@ -684,7 +684,7 @@ dns_namedec(uint8_t *outdata, size_t outdatalen, uint8_t *buf, size_t buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_dns_withq(int dns_fd, int tun_fd, uint8_t *buf, size_t buflen, struct query *q)
|
read_dns_withq(uint8_t *buf, size_t buflen, struct query *q)
|
||||||
/* Returns -1 on receive error or decode error, including DNS error replies.
|
/* Returns -1 on receive error or decode error, including DNS error replies.
|
||||||
Returns 0 on replies that could be correct but are useless, and are not
|
Returns 0 on replies that could be correct but are useless, and are not
|
||||||
DNS error replies.
|
DNS error replies.
|
||||||
@ -697,7 +697,7 @@ read_dns_withq(int dns_fd, int tun_fd, uint8_t *buf, size_t buflen, struct query
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
addrlen = sizeof(from);
|
addrlen = sizeof(from);
|
||||||
if ((r = recvfrom(dns_fd, data, sizeof(data), 0,
|
if ((r = recvfrom(this.dns_fd, data, sizeof(data), 0,
|
||||||
(struct sockaddr*)&from, &addrlen)) < 0) {
|
(struct sockaddr*)&from, &addrlen)) < 0) {
|
||||||
warn("recvfrom");
|
warn("recvfrom");
|
||||||
return -1;
|
return -1;
|
||||||
@ -787,7 +787,7 @@ read_dns_withq(int dns_fd, int tun_fd, uint8_t *buf, size_t buflen, struct query
|
|||||||
r -= RAW_HDR_LEN;
|
r -= RAW_HDR_LEN;
|
||||||
datalen = sizeof(buf);
|
datalen = sizeof(buf);
|
||||||
if (uncompress(buf, &datalen, data + RAW_HDR_LEN, r) == Z_OK) {
|
if (uncompress(buf, &datalen, data + RAW_HDR_LEN, r) == Z_OK) {
|
||||||
write_tun(tun_fd, buf, datalen);
|
write_tun(this.tun_fd, buf, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all done */
|
/* all done */
|
||||||
@ -796,7 +796,7 @@ read_dns_withq(int dns_fd, int tun_fd, uint8_t *buf, size_t buflen, struct query
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout)
|
handshake_waitdns(char *buf, size_t buflen, char cmd, int timeout)
|
||||||
/* Wait for DNS reply fitting to our latest query and returns it.
|
/* Wait for DNS reply fitting to our latest query and returns it.
|
||||||
Returns length of reply = #bytes used in buf.
|
Returns length of reply = #bytes used in buf.
|
||||||
Returns 0 if fitting reply happens to be useless.
|
Returns 0 if fitting reply happens to be useless.
|
||||||
@ -821,8 +821,8 @@ handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout)
|
|||||||
tv.tv_sec = timeout;
|
tv.tv_sec = timeout;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(dns_fd, &fds);
|
FD_SET(this.dns_fd, &fds);
|
||||||
r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
|
r = select(this.dns_fd + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -1; /* select error */
|
return -1; /* select error */
|
||||||
@ -831,7 +831,7 @@ handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout)
|
|||||||
|
|
||||||
q.id = -1;
|
q.id = -1;
|
||||||
q.name[0] = '\0';
|
q.name[0] = '\0';
|
||||||
rv = read_dns_withq(dns_fd, 0, (uint8_t *)buf, buflen, &q);
|
rv = read_dns_withq((uint8_t *)buf, buflen, &q);
|
||||||
|
|
||||||
qcmd = toupper(q.name[0]);
|
qcmd = toupper(q.name[0]);
|
||||||
if (q.id != this.chunkid || qcmd != cmd) {
|
if (q.id != this.chunkid || qcmd != cmd) {
|
||||||
@ -920,7 +920,7 @@ parse_data(uint8_t *data, size_t len, fragment *f, int *immediate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tunnel_tun(int tun_fd, int dns_fd)
|
tunnel_tun()
|
||||||
{
|
{
|
||||||
size_t datalen;
|
size_t datalen;
|
||||||
uint8_t out[64*1024];
|
uint8_t out[64*1024];
|
||||||
@ -928,7 +928,7 @@ tunnel_tun(int tun_fd, int dns_fd)
|
|||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
|
|
||||||
if ((read = read_tun(tun_fd, in, sizeof(in))) <= 0)
|
if ((read = read_tun(this.tun_fd, in, sizeof(in))) <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
DEBUG(2, " IN: %lu bytes on tunnel, to be compressed: %d", read, this.compression_up);
|
DEBUG(2, " IN: %lu bytes on tunnel, to be compressed: %d", read, this.compression_up);
|
||||||
@ -953,14 +953,14 @@ tunnel_tun(int tun_fd, int dns_fd)
|
|||||||
window_add_outgoing_data(this.outbuf, data, datalen, this.compression_up);
|
window_add_outgoing_data(this.outbuf, data, datalen, this.compression_up);
|
||||||
/* Don't send anything here to respect min. send interval */
|
/* Don't send anything here to respect min. send interval */
|
||||||
} else {
|
} else {
|
||||||
send_raw_data(dns_fd, data, datalen);
|
send_raw_data(data, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tunnel_dns(int tun_fd, int dns_fd)
|
tunnel_dns()
|
||||||
{
|
{
|
||||||
struct query q;
|
struct query q;
|
||||||
size_t datalen, buflen;
|
size_t datalen, buflen;
|
||||||
@ -971,7 +971,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
|||||||
memset(&q, 0, sizeof(q));
|
memset(&q, 0, sizeof(q));
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
memset(cbuf, 0, sizeof(cbuf));
|
memset(cbuf, 0, sizeof(cbuf));
|
||||||
read = read_dns_withq(dns_fd, tun_fd, cbuf, sizeof(cbuf), &q);
|
read = read_dns_withq(cbuf, sizeof(cbuf), &q);
|
||||||
|
|
||||||
if (this.conn != CONN_DNS_NULL)
|
if (this.conn != CONN_DNS_NULL)
|
||||||
return 1; /* everything already done */
|
return 1; /* everything already done */
|
||||||
@ -1016,7 +1016,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
|||||||
/* Reset query counts this.stats */
|
/* Reset query counts this.stats */
|
||||||
this.send_query_sendcnt = 0;
|
this.send_query_sendcnt = 0;
|
||||||
this.send_query_recvcnt = 0;
|
this.send_query_recvcnt = 0;
|
||||||
update_server_timeout(dns_fd, 1);
|
update_server_timeout(1);
|
||||||
|
|
||||||
} else if (this.send_query_recvcnt < 500 && this.num_servfail >= 40 &&
|
} else if (this.send_query_recvcnt < 500 && this.num_servfail >= 40 &&
|
||||||
this.autodetect_server_timeout && this.max_timeout_ms < 500) {
|
this.autodetect_server_timeout && this.max_timeout_ms < 500) {
|
||||||
@ -1024,7 +1024,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
|||||||
/* last-ditch attempt to fix SERVFAILs - disable lazy mode */
|
/* last-ditch attempt to fix SERVFAILs - disable lazy mode */
|
||||||
immediate_mode_defaults();
|
immediate_mode_defaults();
|
||||||
fprintf(stderr, "Attempting to disable lazy mode due to excessive SERVFAILs\n");
|
fprintf(stderr, "Attempting to disable lazy mode due to excessive SERVFAILs\n");
|
||||||
handshake_switch_options(dns_fd, 0, this.compression_down, this.downenc);
|
handshake_switch_options(0, this.compression_down, this.downenc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1111,7 +1111,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (datalen)
|
if (datalen)
|
||||||
write_tun(tun_fd, data, datalen);
|
write_tun(this.tun_fd, data, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move window along after doing all data processing */
|
/* Move window along after doing all data processing */
|
||||||
@ -1121,7 +1121,7 @@ tunnel_dns(int tun_fd, int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
client_tunnel(int tun_fd, int dns_fd)
|
client_tunnel()
|
||||||
{
|
{
|
||||||
struct timeval tv, nextresend, tmp, now, now2;
|
struct timeval tv, nextresend, tmp, now, now2;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
@ -1180,10 +1180,10 @@ client_tunnel(int tun_fd, int dns_fd)
|
|||||||
|
|
||||||
if (sending > 0) {
|
if (sending > 0) {
|
||||||
/* More to send - next fragment */
|
/* More to send - next fragment */
|
||||||
send_next_frag(dns_fd);
|
send_next_frag();
|
||||||
} else {
|
} else {
|
||||||
/* Send ping if we didn't send anything yet */
|
/* Send ping if we didn't send anything yet */
|
||||||
send_ping(dns_fd, 0, this.next_downstream_ack, (this.num_pings > 20 && this.num_pings % 50 == 0));
|
send_ping(0, this.next_downstream_ack, (this.num_pings > 20 && this.num_pings % 50 == 0));
|
||||||
this.next_downstream_ack = -1;
|
this.next_downstream_ack = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1255,9 +1255,9 @@ client_tunnel(int tun_fd, int dns_fd)
|
|||||||
if (this.conn != CONN_DNS_NULL || window_buffer_available(this.outbuf) > 16) {
|
if (this.conn != CONN_DNS_NULL || window_buffer_available(this.outbuf) > 16) {
|
||||||
/* Fill up outgoing buffer with available data if it has enough space
|
/* Fill up outgoing buffer with available data if it has enough space
|
||||||
* The windowing protocol manages data retransmits, timeouts etc. */
|
* The windowing protocol manages data retransmits, timeouts etc. */
|
||||||
FD_SET(tun_fd, &fds);
|
FD_SET(this.tun_fd, &fds);
|
||||||
}
|
}
|
||||||
FD_SET(dns_fd, &fds);
|
FD_SET(this.dns_fd, &fds);
|
||||||
|
|
||||||
DEBUG(4, "Waiting %ld ms before sending more... (min_send %d)", timeval_to_ms(&tv), use_min_send);
|
DEBUG(4, "Waiting %ld ms before sending more... (min_send %d)", timeval_to_ms(&tv), use_min_send);
|
||||||
|
|
||||||
@ -1265,7 +1265,7 @@ client_tunnel(int tun_fd, int dns_fd)
|
|||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = select(MAX(tun_fd, dns_fd) + 1, &fds, NULL, NULL, &tv);
|
i = select(MAX(this.tun_fd, this.dns_fd) + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
if (use_min_send && i > 0) {
|
if (use_min_send && i > 0) {
|
||||||
/* enforce min_send_interval if we get interrupted by new tun data */
|
/* enforce min_send_interval if we get interrupted by new tun data */
|
||||||
@ -1291,8 +1291,8 @@ client_tunnel(int tun_fd, int dns_fd)
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
/* timed out - no new packets recv'd */
|
/* timed out - no new packets recv'd */
|
||||||
} else {
|
} else {
|
||||||
if (FD_ISSET(tun_fd, &fds)) {
|
if (FD_ISSET(this.tun_fd, &fds)) {
|
||||||
if (tunnel_tun(tun_fd, dns_fd) <= 0)
|
if (tunnel_tun() <= 0)
|
||||||
continue;
|
continue;
|
||||||
/* Returns -1 on error OR when quickly
|
/* Returns -1 on error OR when quickly
|
||||||
dropping data in case of DNS congestion;
|
dropping data in case of DNS congestion;
|
||||||
@ -1300,8 +1300,8 @@ client_tunnel(int tun_fd, int dns_fd)
|
|||||||
If chunk sent, sets this.send_ping_soon=0. */
|
If chunk sent, sets this.send_ping_soon=0. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(dns_fd, &fds)) {
|
if (FD_ISSET(this.dns_fd, &fds)) {
|
||||||
tunnel_dns(tun_fd, dns_fd);
|
tunnel_dns();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1310,7 +1310,7 @@ client_tunnel(int tun_fd, int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_login(int fd, char *login, int len)
|
send_login(char *login, int len)
|
||||||
{
|
{
|
||||||
uint8_t data[19];
|
uint8_t data[19];
|
||||||
|
|
||||||
@ -1323,11 +1323,11 @@ send_login(int fd, char *login, int len)
|
|||||||
|
|
||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
send_packet(fd, 'l', data, sizeof(data));
|
send_packet('l', data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_fragsize_probe(int fd, uint16_t fragsize)
|
send_fragsize_probe(uint16_t fragsize)
|
||||||
{
|
{
|
||||||
uint8_t probedata[256];
|
uint8_t probedata[256];
|
||||||
uint8_t buf[MAX_FRAGSIZE];
|
uint8_t buf[MAX_FRAGSIZE];
|
||||||
@ -1350,11 +1350,11 @@ send_fragsize_probe(int fd, uint16_t fragsize)
|
|||||||
build_hostname(buf, sizeof(buf), probedata, sizeof(probedata), this.topdomain,
|
build_hostname(buf, sizeof(buf), probedata, sizeof(probedata), this.topdomain,
|
||||||
this.dataenc, this.hostname_maxlen, 6);
|
this.dataenc, this.hostname_maxlen, 6);
|
||||||
|
|
||||||
send_query(fd, buf);
|
send_query(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_set_downstream_fragsize(int fd, uint16_t fragsize)
|
send_set_downstream_fragsize(uint16_t fragsize)
|
||||||
{
|
{
|
||||||
uint8_t data[5];
|
uint8_t data[5];
|
||||||
|
|
||||||
@ -1365,11 +1365,11 @@ send_set_downstream_fragsize(int fd, uint16_t fragsize)
|
|||||||
|
|
||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
send_packet(fd, 'n', data, sizeof(data));
|
send_packet('n', data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_version(int fd, uint32_t version)
|
send_version(uint32_t version)
|
||||||
{
|
{
|
||||||
uint8_t data[6];
|
uint8_t data[6];
|
||||||
|
|
||||||
@ -1381,11 +1381,11 @@ send_version(int fd, uint32_t version)
|
|||||||
|
|
||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
send_packet(fd, 'v', data, sizeof(data));
|
send_packet('v', data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_ip_request(int fd, int userid)
|
send_ip_request()
|
||||||
{
|
{
|
||||||
uint8_t buf[512] = "i____.";
|
uint8_t buf[512] = "i____.";
|
||||||
buf[1] = b32_5to8(this.userid);
|
buf[1] = b32_5to8(this.userid);
|
||||||
@ -1396,20 +1396,20 @@ send_ip_request(int fd, int userid)
|
|||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
strncat((char *)buf, this.topdomain, 512 - strlen((char *)buf));
|
strncat((char *)buf, this.topdomain, 512 - strlen((char *)buf));
|
||||||
send_query(fd, buf);
|
send_query(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_raw_udp_login(int dns_fd, int userid, int seed)
|
send_raw_udp_login(int seed)
|
||||||
{
|
{
|
||||||
char buf[16];
|
char buf[16];
|
||||||
login_calculate(buf, 16, this.password, seed + 1);
|
login_calculate(buf, 16, this.password, seed + 1);
|
||||||
|
|
||||||
send_raw(dns_fd, (uint8_t *) buf, sizeof(buf), this.userid, RAW_HDR_CMD_LOGIN);
|
send_raw((uint8_t *) buf, sizeof(buf), RAW_HDR_CMD_LOGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_upenctest(int fd, char *s)
|
send_upenctest(char *s)
|
||||||
/* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */
|
/* NOTE: String may be at most 63-4=59 chars to fit in 1 dns chunk. */
|
||||||
{
|
{
|
||||||
char buf[512] = "z___";
|
char buf[512] = "z___";
|
||||||
@ -1422,16 +1422,16 @@ send_upenctest(int fd, char *s)
|
|||||||
strncat(buf, s, 512 - strlen(buf));
|
strncat(buf, s, 512 - strlen(buf));
|
||||||
strncat(buf, ".", 512 - strlen(buf));
|
strncat(buf, ".", 512 - strlen(buf));
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
strncat(buf, this.topdomain, 512 - strlen(buf));
|
||||||
send_query(fd, (uint8_t *)buf);
|
send_query((uint8_t *)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_downenctest(int fd, char downenc, int variant, char *s, int slen)
|
send_downenctest(char downenc, int variant, char *s, int slen)
|
||||||
/* Note: content/handling of s is not defined yet. */
|
/* Note: content/handling of s is not defined yet. */
|
||||||
{
|
{
|
||||||
char buf[512] = "y_____.";
|
char buf[512] = "y_____.";
|
||||||
|
|
||||||
buf[1] = tolower(this.downenc);
|
buf[1] = tolower(downenc);
|
||||||
buf[2] = b32_5to8(variant);
|
buf[2] = b32_5to8(variant);
|
||||||
|
|
||||||
buf[3] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
buf[3] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
||||||
@ -1440,11 +1440,11 @@ send_downenctest(int fd, char downenc, int variant, char *s, int slen)
|
|||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
strncat(buf, this.topdomain, 512 - strlen(buf));
|
||||||
send_query(fd, (uint8_t *)buf);
|
send_query((uint8_t *)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_codec_switch(int fd, int userid, int bits)
|
send_codec_switch(int bits)
|
||||||
{
|
{
|
||||||
char buf[512] = "s_____.";
|
char buf[512] = "s_____.";
|
||||||
buf[1] = b32_5to8(this.userid);
|
buf[1] = b32_5to8(this.userid);
|
||||||
@ -1456,11 +1456,11 @@ send_codec_switch(int fd, int userid, int bits)
|
|||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
strncat(buf, this.topdomain, 512 - strlen(buf));
|
||||||
send_query(fd, (uint8_t *)buf);
|
send_query((uint8_t *)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_server_options(int fd, int userid, int lazy, int compression, char denc, char *options)
|
send_server_options(int lazy, int compression, char denc, char *options)
|
||||||
/* Options must be length >=4 */
|
/* Options must be length >=4 */
|
||||||
{
|
{
|
||||||
char buf[512] = "oU3___CMC.";
|
char buf[512] = "oU3___CMC.";
|
||||||
@ -1478,11 +1478,11 @@ send_server_options(int fd, int userid, int lazy, int compression, char denc, ch
|
|||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
strncat(buf, this.topdomain, 512 - strlen(buf));
|
||||||
send_query(fd, (uint8_t *)buf);
|
send_query((uint8_t *)buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_version(int dns_fd, int *seed)
|
handshake_version(int *seed)
|
||||||
{
|
{
|
||||||
char hex[] = "0123456789abcdef";
|
char hex[] = "0123456789abcdef";
|
||||||
char hex2[] = "0123456789ABCDEF";
|
char hex2[] = "0123456789ABCDEF";
|
||||||
@ -1493,9 +1493,9 @@ handshake_version(int dns_fd, int *seed)
|
|||||||
|
|
||||||
for (i = 0; this.running && i < 5; i++) {
|
for (i = 0; this.running && i < 5; i++) {
|
||||||
|
|
||||||
send_version(dns_fd, PROTOCOL_VERSION);
|
send_version(PROTOCOL_VERSION);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'V', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'V', i+1);
|
||||||
|
|
||||||
if (read >= 9) {
|
if (read >= 9) {
|
||||||
payload = (((in[4] & 0xff) << 24) |
|
payload = (((in[4] & 0xff) << 24) |
|
||||||
@ -1530,7 +1530,7 @@ handshake_version(int dns_fd, int *seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_login(int dns_fd, int seed)
|
handshake_login(int seed)
|
||||||
{
|
{
|
||||||
char in[4096];
|
char in[4096];
|
||||||
char login[16];
|
char login[16];
|
||||||
@ -1544,9 +1544,9 @@ handshake_login(int dns_fd, int seed)
|
|||||||
|
|
||||||
for (i=0; this.running && i<5 ;i++) {
|
for (i=0; this.running && i<5 ;i++) {
|
||||||
|
|
||||||
send_login(dns_fd, login, 16);
|
send_login(login, 16);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'L', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'L', i+1);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
int netmask;
|
int netmask;
|
||||||
@ -1578,7 +1578,7 @@ handshake_login(int dns_fd, int seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_raw_udp(int dns_fd, int seed)
|
handshake_raw_udp(int seed)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
char in[4096];
|
char in[4096];
|
||||||
@ -1594,9 +1594,9 @@ handshake_raw_udp(int dns_fd, int seed)
|
|||||||
fprintf(stderr, "Testing raw UDP data to the server (skip with -r)");
|
fprintf(stderr, "Testing raw UDP data to the server (skip with -r)");
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_ip_request(dns_fd, this.userid);
|
send_ip_request();
|
||||||
|
|
||||||
len = handshake_waitdns(dns_fd, in, sizeof(in), 'I', i+1);
|
len = handshake_waitdns(in, sizeof(in), 'I', i+1);
|
||||||
|
|
||||||
if (len == 5 && in[0] == 'I') {
|
if (len == 5 && in[0] == 'I') {
|
||||||
/* Received IPv4 address */
|
/* Received IPv4 address */
|
||||||
@ -1640,16 +1640,16 @@ handshake_raw_udp(int dns_fd, int seed)
|
|||||||
tv.tv_sec = i + 1;
|
tv.tv_sec = i + 1;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
send_raw_udp_login(dns_fd, this.userid, seed);
|
send_raw_udp_login(seed);
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(dns_fd, &fds);
|
FD_SET(this.dns_fd, &fds);
|
||||||
|
|
||||||
r = select(dns_fd + 1, &fds, NULL, NULL, &tv);
|
r = select(this.dns_fd + 1, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
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(this.dns_fd, in, sizeof(in), 0);
|
||||||
if (len >= (16 + RAW_HDR_LEN)) {
|
if (len >= (16 + RAW_HDR_LEN)) {
|
||||||
char hash[16];
|
char hash[16];
|
||||||
login_calculate(hash, 16, this.password, seed - 1);
|
login_calculate(hash, 16, this.password, seed - 1);
|
||||||
@ -1671,7 +1671,7 @@ handshake_raw_udp(int dns_fd, int seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_upenctest(int dns_fd, char *s)
|
handshake_upenctest(char *s)
|
||||||
/* NOTE: *s may be max 59 chars; must start with "aA" for case-swap check
|
/* NOTE: *s may be max 59 chars; must start with "aA" for case-swap check
|
||||||
Returns:
|
Returns:
|
||||||
-1: case swap, no need for any further test: error printed; or Ctrl-C
|
-1: case swap, no need for any further test: error printed; or Ctrl-C
|
||||||
@ -1689,9 +1689,9 @@ handshake_upenctest(int dns_fd, char *s)
|
|||||||
slen = strlen(s);
|
slen = strlen(s);
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_upenctest(dns_fd, s);
|
send_upenctest(s);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'Z', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'Z', i+1);
|
||||||
|
|
||||||
if (read == -2)
|
if (read == -2)
|
||||||
return 0; /* hard error */
|
return 0; /* hard error */
|
||||||
@ -1741,7 +1741,7 @@ handshake_upenctest(int dns_fd, char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_upenc_autodetect(int dns_fd)
|
handshake_upenc_autodetect()
|
||||||
/* Returns:
|
/* Returns:
|
||||||
0: keep Base32
|
0: keep Base32
|
||||||
1: Base64 is okay
|
1: Base64 is okay
|
||||||
@ -1771,7 +1771,7 @@ handshake_upenc_autodetect(int dns_fd)
|
|||||||
|
|
||||||
/* Try Base128, starting very gently to not draw attention */
|
/* Try Base128, starting very gently to not draw attention */
|
||||||
while (1) {
|
while (1) {
|
||||||
res = handshake_upenctest(dns_fd, pat128a);
|
res = handshake_upenctest(pat128a);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
/* DNS swaps case, msg already printed; or Ctrl-C */
|
/* DNS swaps case, msg already printed; or Ctrl-C */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1780,7 +1780,7 @@ handshake_upenc_autodetect(int dns_fd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = handshake_upenctest(dns_fd, pat128b);
|
res = handshake_upenctest(pat128b);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return 0;
|
return 0;
|
||||||
else if (res == 0)
|
else if (res == 0)
|
||||||
@ -1788,19 +1788,19 @@ handshake_upenc_autodetect(int dns_fd)
|
|||||||
|
|
||||||
/* if this works, we can test the real stuff */
|
/* if this works, we can test the real stuff */
|
||||||
|
|
||||||
res = handshake_upenctest(dns_fd, pat128c);
|
res = handshake_upenctest(pat128c);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return 0;
|
return 0;
|
||||||
else if (res == 0)
|
else if (res == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
res = handshake_upenctest(dns_fd, pat128d);
|
res = handshake_upenctest(pat128d);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return 0;
|
return 0;
|
||||||
else if (res == 0)
|
else if (res == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
res = handshake_upenctest(dns_fd, pat128e);
|
res = handshake_upenctest(pat128e);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return 0;
|
return 0;
|
||||||
else if (res == 0)
|
else if (res == 0)
|
||||||
@ -1811,7 +1811,7 @@ handshake_upenc_autodetect(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try Base64 (with plus sign) */
|
/* Try Base64 (with plus sign) */
|
||||||
res = handshake_upenctest(dns_fd, pat64);
|
res = handshake_upenctest(pat64);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
/* DNS swaps case, msg already printed; or Ctrl-C */
|
/* DNS swaps case, msg already printed; or Ctrl-C */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1821,7 +1821,7 @@ handshake_upenc_autodetect(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try Base64u (with _u_nderscore) */
|
/* Try Base64u (with _u_nderscore) */
|
||||||
res = handshake_upenctest(dns_fd, pat64u);
|
res = handshake_upenctest(pat64u);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
/* DNS swaps case, msg already printed; or Ctrl-C */
|
/* DNS swaps case, msg already printed; or Ctrl-C */
|
||||||
return 0;
|
return 0;
|
||||||
@ -1836,7 +1836,7 @@ handshake_upenc_autodetect(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_downenctest(int dns_fd, char trycodec)
|
handshake_downenctest(char trycodec)
|
||||||
/* Returns:
|
/* Returns:
|
||||||
0: not identical or error or timeout
|
0: not identical or error or timeout
|
||||||
1: identical string returned
|
1: identical string returned
|
||||||
@ -1850,9 +1850,9 @@ handshake_downenctest(int dns_fd, char trycodec)
|
|||||||
|
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_downenctest(dns_fd, trycodec, 1, NULL, 0);
|
send_downenctest(trycodec, 1, NULL, 0);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'Y', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'Y', i+1);
|
||||||
|
|
||||||
if (read == -2)
|
if (read == -2)
|
||||||
return 0; /* hard error */
|
return 0; /* hard error */
|
||||||
@ -1880,7 +1880,7 @@ handshake_downenctest(int dns_fd, char trycodec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char
|
static char
|
||||||
handshake_downenc_autodetect(int dns_fd)
|
handshake_downenc_autodetect()
|
||||||
/* Returns codec char (or ' ' if no advanced codec works) */
|
/* Returns codec char (or ' ' if no advanced codec works) */
|
||||||
{
|
{
|
||||||
int base64ok = 0;
|
int base64ok = 0;
|
||||||
@ -1896,20 +1896,20 @@ handshake_downenc_autodetect(int dns_fd)
|
|||||||
fprintf(stderr, "Autodetecting downstream codec (use -O to override)\n");
|
fprintf(stderr, "Autodetecting downstream codec (use -O to override)\n");
|
||||||
|
|
||||||
/* Try Base64 */
|
/* Try Base64 */
|
||||||
if (handshake_downenctest(dns_fd, 'S'))
|
if (handshake_downenctest('S'))
|
||||||
base64ok = 1;
|
base64ok = 1;
|
||||||
else if (this.running && handshake_downenctest(dns_fd, 'U'))
|
else if (this.running && handshake_downenctest('U'))
|
||||||
base64uok = 1;
|
base64uok = 1;
|
||||||
|
|
||||||
/* Try Base128 only if 64 gives us some perspective */
|
/* Try Base128 only if 64 gives us some perspective */
|
||||||
if (this.running && (base64ok || base64uok)) {
|
if (this.running && (base64ok || base64uok)) {
|
||||||
if (handshake_downenctest(dns_fd, 'V'))
|
if (handshake_downenctest('V'))
|
||||||
base128ok = 1;
|
base128ok = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If 128 works, then TXT may give us Raw as well */
|
/* If 128 works, then TXT may give us Raw as well */
|
||||||
if (this.running && (base128ok && this.do_qtype == T_TXT)) {
|
if (this.running && (base128ok && this.do_qtype == T_TXT)) {
|
||||||
if (handshake_downenctest(dns_fd, 'R'))
|
if (handshake_downenctest('R'))
|
||||||
return 'R';
|
return 'R';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1928,7 +1928,7 @@ handshake_downenc_autodetect(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_qtypetest(int dns_fd, int timeout)
|
handshake_qtypetest(int timeout)
|
||||||
/* Returns:
|
/* Returns:
|
||||||
0: doesn't work with this timeout
|
0: doesn't work with this timeout
|
||||||
1: works properly
|
1: works properly
|
||||||
@ -1950,9 +1950,9 @@ handshake_qtypetest(int dns_fd, int timeout)
|
|||||||
byte values can be returned, which is needed for NULL/PRIVATE
|
byte values can be returned, which is needed for NULL/PRIVATE
|
||||||
to work. */
|
to work. */
|
||||||
|
|
||||||
send_downenctest(dns_fd, trycodec, 1, NULL, 0);
|
send_downenctest(trycodec, 1, NULL, 0);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'Y', timeout);
|
read = handshake_waitdns(in, sizeof(in), 'Y', timeout);
|
||||||
|
|
||||||
if (read != slen)
|
if (read != slen)
|
||||||
return 0; /* incorrect */
|
return 0; /* incorrect */
|
||||||
@ -1984,7 +1984,7 @@ handshake_qtype_numcvt(int num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_qtype_autodetect(int dns_fd)
|
handshake_qtype_autodetect()
|
||||||
/* Returns:
|
/* Returns:
|
||||||
0: okay, this.do_qtype set
|
0: okay, this.do_qtype set
|
||||||
1: problem, program exit
|
1: problem, program exit
|
||||||
@ -2016,7 +2016,7 @@ handshake_qtype_autodetect(int dns_fd)
|
|||||||
fprintf(stderr, ".");
|
fprintf(stderr, ".");
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
if (handshake_qtypetest(dns_fd, timeout)) {
|
if (handshake_qtypetest(timeout)) {
|
||||||
/* okay */
|
/* okay */
|
||||||
highestworking = qtypenum;
|
highestworking = qtypenum;
|
||||||
DEBUG(1, " Type %s timeout %d works", client_get_qtype(), timeout);
|
DEBUG(1, " Type %s timeout %d works", client_get_qtype(), timeout);
|
||||||
@ -2053,7 +2053,7 @@ handshake_qtype_autodetect(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_edns0_check(int dns_fd)
|
handshake_edns0_check()
|
||||||
/* Returns:
|
/* Returns:
|
||||||
0: EDNS0 not supported; or Ctrl-C
|
0: EDNS0 not supported; or Ctrl-C
|
||||||
1: EDNS0 works
|
1: EDNS0 works
|
||||||
@ -2073,9 +2073,9 @@ handshake_edns0_check(int dns_fd)
|
|||||||
|
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_downenctest(dns_fd, trycodec, 1, NULL, 0);
|
send_downenctest(trycodec, 1, NULL, 0);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'Y', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'Y', i+1);
|
||||||
|
|
||||||
if (read == -2)
|
if (read == -2)
|
||||||
return 0; /* hard error */
|
return 0; /* hard error */
|
||||||
@ -2103,7 +2103,7 @@ handshake_edns0_check(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handshake_switch_codec(int dns_fd, int bits)
|
handshake_switch_codec(int bits)
|
||||||
{
|
{
|
||||||
char in[4096];
|
char in[4096];
|
||||||
int i;
|
int i;
|
||||||
@ -2124,9 +2124,9 @@ handshake_switch_codec(int dns_fd, int bits)
|
|||||||
|
|
||||||
for (i=0; this.running && i<5 ;i++) {
|
for (i=0; this.running && i<5 ;i++) {
|
||||||
|
|
||||||
send_codec_switch(dns_fd, this.userid, bits);
|
send_codec_switch(bits);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'S', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'S', i+1);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
if (strncmp("BADLEN", in, 6) == 0) {
|
if (strncmp("BADLEN", in, 6) == 0) {
|
||||||
@ -2160,7 +2160,7 @@ codec_revert:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
handshake_switch_options(int dns_fd, int lazy, int compression, char denc)
|
handshake_switch_options(int lazy, int compression, char denc)
|
||||||
{
|
{
|
||||||
char in[4096];
|
char in[4096];
|
||||||
int read;
|
int read;
|
||||||
@ -2185,9 +2185,9 @@ handshake_switch_options(int dns_fd, int lazy, int compression, char denc)
|
|||||||
lazy_status, dname, comp_status);
|
lazy_status, dname, comp_status);
|
||||||
for (int i = 0; this.running && i < 5; i++) {
|
for (int i = 0; this.running && i < 5; i++) {
|
||||||
|
|
||||||
send_server_options(dns_fd, this.userid, lazy, compression, denc, opts);
|
send_server_options(lazy, compression, denc, opts);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in) - 1, 'O', i + 1);
|
read = handshake_waitdns(in, sizeof(in) - 1, 'O', i + 1);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
if (strncmp("BADLEN", in, 6) == 0) {
|
if (strncmp("BADLEN", in, 6) == 0) {
|
||||||
@ -2295,7 +2295,7 @@ fragsize_check(char *in, int read, int proposed_fragsize, int *max_fragsize)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handshake_autoprobe_fragsize(int dns_fd)
|
handshake_autoprobe_fragsize()
|
||||||
{
|
{
|
||||||
char in[MAX_FRAGSIZE];
|
char in[MAX_FRAGSIZE];
|
||||||
int i;
|
int i;
|
||||||
@ -2310,9 +2310,9 @@ handshake_autoprobe_fragsize(int dns_fd)
|
|||||||
/* stop the slow probing early when we have enough bytes anyway */
|
/* stop the slow probing early when we have enough bytes anyway */
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_fragsize_probe(dns_fd, proposed_fragsize);
|
send_fragsize_probe(proposed_fragsize);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'R', 1);
|
read = handshake_waitdns(in, sizeof(in), 'R', 1);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
/* We got a reply */
|
/* We got a reply */
|
||||||
@ -2367,7 +2367,7 @@ handshake_autoprobe_fragsize(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handshake_set_fragsize(int dns_fd, int fragsize)
|
handshake_set_fragsize(int fragsize)
|
||||||
{
|
{
|
||||||
char in[4096];
|
char in[4096];
|
||||||
int i;
|
int i;
|
||||||
@ -2376,9 +2376,9 @@ handshake_set_fragsize(int dns_fd, int fragsize)
|
|||||||
fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize);
|
fprintf(stderr, "Setting downstream fragment size to max %d...\n", fragsize);
|
||||||
for (i=0; this.running && i<5 ;i++) {
|
for (i=0; this.running && i<5 ;i++) {
|
||||||
|
|
||||||
send_set_downstream_fragsize(dns_fd, fragsize);
|
send_set_downstream_fragsize(fragsize);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'N', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'N', i+1);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
|
|
||||||
@ -2404,7 +2404,7 @@ handshake_set_fragsize(int dns_fd, int fragsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handshake_set_timeout(int dns_fd)
|
handshake_set_timeout()
|
||||||
{
|
{
|
||||||
char in[4096];
|
char in[4096];
|
||||||
int read, id;
|
int read, id;
|
||||||
@ -2419,9 +2419,9 @@ handshake_set_timeout(int dns_fd)
|
|||||||
for (int i = 0; this.running && i < 5; i++) {
|
for (int i = 0; this.running && i < 5; i++) {
|
||||||
|
|
||||||
id = this.autodetect_server_timeout ?
|
id = this.autodetect_server_timeout ?
|
||||||
update_server_timeout(dns_fd, 1) : send_ping(dns_fd, 1, -1, 1);
|
update_server_timeout(1) : send_ping(1, -1, 1);
|
||||||
|
|
||||||
read = handshake_waitdns(dns_fd, in, sizeof(in), 'P', i + 1);
|
read = handshake_waitdns(in, sizeof(in), 'P', i + 1);
|
||||||
got_response(id, 1, 0);
|
got_response(id, 1, 0);
|
||||||
|
|
||||||
fprintf(stderr, ".");
|
fprintf(stderr, ".");
|
||||||
@ -2447,7 +2447,7 @@ handshake_set_timeout(int dns_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize)
|
client_handshake()
|
||||||
{
|
{
|
||||||
int seed;
|
int seed;
|
||||||
int upcodec;
|
int upcodec;
|
||||||
@ -2457,7 +2457,7 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
|
|||||||
|
|
||||||
/* qtype message printed in handshake function */
|
/* qtype message printed in handshake function */
|
||||||
if (this.do_qtype == T_UNSET) {
|
if (this.do_qtype == T_UNSET) {
|
||||||
r = handshake_qtype_autodetect(dns_fd);
|
r = handshake_qtype_autodetect();
|
||||||
if (r) {
|
if (r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2465,28 +2465,28 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
|
|||||||
|
|
||||||
fprintf(stderr, "Using DNS type %s queries\n", client_get_qtype());
|
fprintf(stderr, "Using DNS type %s queries\n", client_get_qtype());
|
||||||
|
|
||||||
r = handshake_version(dns_fd, &seed);
|
r = handshake_version(&seed);
|
||||||
if (r) {
|
if (r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = handshake_login(dns_fd, seed);
|
r = handshake_login(seed);
|
||||||
if (r) {
|
if (r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw_mode && handshake_raw_udp(dns_fd, seed)) {
|
if (this.raw_mode && handshake_raw_udp(seed)) {
|
||||||
this.conn = CONN_RAW_UDP;
|
this.conn = CONN_RAW_UDP;
|
||||||
this.max_timeout_ms = 10000;
|
this.max_timeout_ms = 10000;
|
||||||
this.compression_down = 1;
|
this.compression_down = 1;
|
||||||
this.compression_up = 1;
|
this.compression_up = 1;
|
||||||
} else {
|
} else {
|
||||||
if (raw_mode == 0) {
|
if (this.raw_mode == 0) {
|
||||||
fprintf(stderr, "Skipping raw mode\n");
|
fprintf(stderr, "Skipping raw mode\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsc_use_edns0 = 1;
|
dnsc_use_edns0 = 1;
|
||||||
if (handshake_edns0_check(dns_fd) && this.running) {
|
if (handshake_edns0_check() && this.running) {
|
||||||
fprintf(stderr, "Using EDNS0 extension\n");
|
fprintf(stderr, "Using EDNS0 extension\n");
|
||||||
} else if (!this.running) {
|
} else if (!this.running) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -2495,45 +2495,45 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
|
|||||||
dnsc_use_edns0 = 0;
|
dnsc_use_edns0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
upcodec = handshake_upenc_autodetect(dns_fd);
|
upcodec = handshake_upenc_autodetect();
|
||||||
if (!this.running)
|
if (!this.running)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (upcodec == 1) { /* Base64 */
|
if (upcodec == 1) { /* Base64 */
|
||||||
handshake_switch_codec(dns_fd, 6);
|
handshake_switch_codec(6);
|
||||||
} else if (upcodec == 2) { /* Base64u */
|
} else if (upcodec == 2) { /* Base64u */
|
||||||
handshake_switch_codec(dns_fd, 26);
|
handshake_switch_codec(26);
|
||||||
} else if (upcodec == 3) { /* Base128 */
|
} else if (upcodec == 3) { /* Base128 */
|
||||||
handshake_switch_codec(dns_fd, 7);
|
handshake_switch_codec(7);
|
||||||
}
|
}
|
||||||
if (!this.running)
|
if (!this.running)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (this.downenc == ' ') {
|
if (this.downenc == ' ') {
|
||||||
this.downenc = handshake_downenc_autodetect(dns_fd);
|
this.downenc = handshake_downenc_autodetect();
|
||||||
}
|
}
|
||||||
if (!this.running)
|
if (!this.running)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Set options for compression, this.lazymode and downstream codec */
|
/* Set options for compression, this.lazymode and downstream codec */
|
||||||
handshake_switch_options(dns_fd, this.lazymode, this.compression_down, this.downenc);
|
handshake_switch_options(this.lazymode, this.compression_down, this.downenc);
|
||||||
if (!this.running)
|
if (!this.running)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (autodetect_frag_size) {
|
if (this.autodetect_frag_size) {
|
||||||
fragsize = handshake_autoprobe_fragsize(dns_fd);
|
this.max_downstream_frag_size = handshake_autoprobe_fragsize();
|
||||||
if (fragsize > MAX_FRAGSIZE) {
|
if (this.max_downstream_frag_size > MAX_FRAGSIZE) {
|
||||||
/* This is very unlikely except perhaps over LAN */
|
/* This is very unlikely except perhaps over LAN */
|
||||||
fprintf(stderr, "Can transfer fragsize of %d, however iodine has been compiled with MAX_FRAGSIZE = %d."
|
fprintf(stderr, "Can transfer fragsize of %d, however iodine has been compiled with MAX_FRAGSIZE = %d."
|
||||||
" To fully utilize this connection, please recompile iodine/iodined.\n", fragsize, MAX_FRAGSIZE);
|
" To fully utilize this connection, please recompile iodine/iodined.\n", this.max_downstream_frag_size, MAX_FRAGSIZE);
|
||||||
fragsize = MAX_FRAGSIZE;
|
this.max_downstream_frag_size = MAX_FRAGSIZE;
|
||||||
}
|
}
|
||||||
if (!fragsize) {
|
if (!this.max_downstream_frag_size) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handshake_set_fragsize(dns_fd, fragsize);
|
handshake_set_fragsize(this.max_downstream_frag_size);
|
||||||
if (!this.running)
|
if (!this.running)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -2551,7 +2551,7 @@ client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsiz
|
|||||||
this.pending_queries[i].id = -1;
|
this.pending_queries[i].id = -1;
|
||||||
|
|
||||||
/* set server window/timeout parameters and calculate RTT */
|
/* set server window/timeout parameters and calculate RTT */
|
||||||
handshake_set_timeout(dns_fd);
|
handshake_set_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
10
src/client.h
10
src/client.h
@ -153,12 +153,12 @@ char *format_qtype();
|
|||||||
char parse_encoding(char *encoding);
|
char parse_encoding(char *encoding);
|
||||||
void client_set_hostname_maxlen(size_t i);
|
void client_set_hostname_maxlen(size_t i);
|
||||||
|
|
||||||
int client_handshake(int dns_fd, int raw_mode, int autodetect_frag_size, int fragsize);
|
int client_handshake();
|
||||||
int client_tunnel(int tun_fd, int dns_fd);
|
int client_tunnel();
|
||||||
|
|
||||||
int parse_data(uint8_t *data, size_t len, fragment *f, int *immediate);
|
int parse_data(uint8_t *data, size_t len, fragment *f, int *immediate);
|
||||||
int handshake_waitdns(int dns_fd, char *buf, size_t buflen, char cmd, int timeout);
|
int handshake_waitdns(char *buf, size_t buflen, char cmd, int timeout);
|
||||||
void handshake_switch_options(int dns_fd, int lazy, int compression, char denc);
|
void handshake_switch_options(int lazy, int compression, char denc);
|
||||||
int send_ping(int fd, int ping_response, int ack, int timeout);
|
int send_ping(int ping_response, int ack, int timeout);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
161
src/iodine.c
161
src/iodine.c
@ -24,6 +24,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
@ -57,11 +58,20 @@ static char *__progname;
|
|||||||
|
|
||||||
struct client_instance this;
|
struct client_instance this;
|
||||||
|
|
||||||
|
/* BEGIN PRESET DEFINITIONS */
|
||||||
|
|
||||||
|
/* static startup values - should not be changed in presets */
|
||||||
|
#define PRESET_STATIC_VALUES \
|
||||||
|
.conn = CONN_DNS_NULL, \
|
||||||
|
.send_ping_soon = 1, \
|
||||||
|
.downenc = ' ', \
|
||||||
|
.do_qtype = T_UNSET, \
|
||||||
|
.maxfragsize_up = 100, \
|
||||||
|
.next_downstream_ack = -1, \
|
||||||
|
.num_immediate = 1, \
|
||||||
|
.rtt_total_ms = 200
|
||||||
|
|
||||||
static struct client_instance preset_default = {
|
static struct client_instance preset_default = {
|
||||||
.foreground = 0,
|
|
||||||
#ifdef OPENBSD
|
|
||||||
.rtable = 0,
|
|
||||||
#endif
|
|
||||||
.debug = 0,
|
.debug = 0,
|
||||||
.stats = 0,
|
.stats = 0,
|
||||||
.raw_mode = 1,
|
.raw_mode = 1,
|
||||||
@ -79,18 +89,56 @@ static struct client_instance preset_default = {
|
|||||||
.windowsize_up = 8,
|
.windowsize_up = 8,
|
||||||
.windowsize_down = 8,
|
.windowsize_down = 8,
|
||||||
.hostname_maxlen = 0xFF,
|
.hostname_maxlen = 0xFF,
|
||||||
|
PRESET_STATIC_VALUES
|
||||||
/* static startup values - should not be changed in presets */
|
|
||||||
.conn = CONN_DNS_NULL,
|
|
||||||
.send_ping_soon = 1,
|
|
||||||
.downenc = ' ',
|
|
||||||
.do_qtype = T_UNSET,
|
|
||||||
.maxfragsize_up = 100,
|
|
||||||
.next_downstream_ack = -1,
|
|
||||||
.num_immediate = 1,
|
|
||||||
.rtt_total_ms = 200
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct client_instance preset_original = {
|
||||||
|
.raw_mode = 1,
|
||||||
|
.lazymode = 1,
|
||||||
|
.max_timeout_ms = 4000,
|
||||||
|
.send_interval_ms = 0,
|
||||||
|
.server_timeout_ms = 3000,
|
||||||
|
.autodetect_server_timeout = 1,
|
||||||
|
.windowsize_down = 1,
|
||||||
|
.windowsize_up = 1,
|
||||||
|
.hostname_maxlen = 0xFF,
|
||||||
|
.downstream_timeout_ms = 4000,
|
||||||
|
.dataenc = &base32_encoder,
|
||||||
|
.autodetect_frag_size = 1,
|
||||||
|
.max_downstream_frag_size = MAX_FRAGSIZE,
|
||||||
|
.compression_down = 1,
|
||||||
|
.compression_up = 0,
|
||||||
|
PRESET_STATIC_VALUES
|
||||||
|
};
|
||||||
|
|
||||||
|
struct option_presets {
|
||||||
|
size_t preset_data_len; /* sizeof(struct client/server_instance) */
|
||||||
|
size_t num_presets;
|
||||||
|
struct option_preset {
|
||||||
|
void *preset_data; /* Pointer to client/server "instance" struct */
|
||||||
|
char short_name;
|
||||||
|
char *long_name;
|
||||||
|
} presets[];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_CLIENT_PRESETS 2
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
struct client_instance *preset_data;
|
||||||
|
char short_name;
|
||||||
|
} client_presets[NUM_CLIENT_PRESETS] = {
|
||||||
|
{
|
||||||
|
.preset_data = &preset_default,
|
||||||
|
.short_name = 'D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.preset_data = &preset_original,
|
||||||
|
.short_name = 'O'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* END PRESET DEFINITIONS */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sighandler(int sig)
|
sighandler(int sig)
|
||||||
{
|
{
|
||||||
@ -151,14 +199,16 @@ help()
|
|||||||
fprintf(stderr, " -v, --version print version info and exit\n");
|
fprintf(stderr, " -v, --version print version info and exit\n");
|
||||||
fprintf(stderr, " -h, --help print this help and exit\n");
|
fprintf(stderr, " -h, --help print this help and exit\n");
|
||||||
fprintf(stderr, " -V, --stats print connection statistics at given intervals (default: 5 sec)\n");
|
fprintf(stderr, " -V, --stats print connection statistics at given intervals (default: 5 sec)\n");
|
||||||
fprintf(stderr, " -X skip tun device and forward data to/from stdin/out, telling the iodined to\n");
|
/*fprintf(stderr, " -X skip tun device and forward data to/from stdin/out, telling iodined to\n");
|
||||||
fprintf(stderr, " connect to the specified port listening on the server host.\n");
|
fprintf(stderr, " connect to the specified port listening on the server host.\n");
|
||||||
fprintf(stderr, " Can be used with SSH ProxyCommand option. (-X 22)\n");
|
fprintf(stderr, " Can be used with SSH ProxyCommand option. (-X 22)\n");*/
|
||||||
fprintf(stderr, " -f keep running in foreground\n");
|
fprintf(stderr, " -f keep running in foreground\n");
|
||||||
fprintf(stderr, " -D enable debug mode (add more D's to increase debug level)\n");
|
fprintf(stderr, " -D enable debug mode (add more D's to increase debug level)\n");
|
||||||
fprintf(stderr, " -d set tunnel device name\n");
|
fprintf(stderr, " -d set tunnel device name\n");
|
||||||
fprintf(stderr, " -u drop privileges and run as specified user\n");
|
fprintf(stderr, " -u drop privileges and run as specified user\n");
|
||||||
fprintf(stderr, " -F write PID to specified file\n");
|
fprintf(stderr, " -F write PID to specified file\n");
|
||||||
|
fprintf(stderr, " -Y, --preset use a set of predefined options (can be overridden manually)\n");
|
||||||
|
fprintf(stderr, " Available presets: 'O' for iodine 0.7 behaviour, 'F' for fast/low latency settings\n");
|
||||||
fprintf(stderr, " --chroot chroot to given directory\n");
|
fprintf(stderr, " --chroot chroot to given directory\n");
|
||||||
fprintf(stderr, " --context apply specified SELinux context after initialization\n");
|
fprintf(stderr, " --context apply specified SELinux context after initialization\n");
|
||||||
fprintf(stderr, " --rdomain use specified routing domain (OpenBSD only)\n\n");
|
fprintf(stderr, " --rdomain use specified routing domain (OpenBSD only)\n\n");
|
||||||
@ -204,11 +254,6 @@ main(int argc, char **argv)
|
|||||||
WSAStartup(req_version, &wsa_data);
|
WSAStartup(req_version, &wsa_data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
srand((unsigned) time(NULL));
|
|
||||||
this.rand_seed = (uint16_t) rand();
|
|
||||||
this.chunkid = (uint16_t) rand();
|
|
||||||
this.running = 1;
|
|
||||||
|
|
||||||
#if !defined(BSD) && !defined(__GLIBC__)
|
#if !defined(BSD) && !defined(__GLIBC__)
|
||||||
__progname = strrchr(argv[0], '/');
|
__progname = strrchr(argv[0], '/');
|
||||||
if (__progname == NULL)
|
if (__progname == NULL)
|
||||||
@ -227,13 +272,52 @@ main(int argc, char **argv)
|
|||||||
{"rdomain", required_argument, 0, 'R'},
|
{"rdomain", required_argument, 0, 'R'},
|
||||||
{"chrootdir", required_argument, 0, 't'},
|
{"chrootdir", required_argument, 0, 't'},
|
||||||
{"proxycommand", no_argument, 0, 'X'},
|
{"proxycommand", no_argument, 0, 'X'},
|
||||||
|
{"preset", required_argument, 0, 'Y'},
|
||||||
{NULL, 0, 0, 0}
|
{NULL, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *iodine_args_short = "46vfDhrXs:V:c:C:i:j:u:t:d:R:P:w:W:m:M:F:T:O:L:I:";
|
/* Pre-parse command line to get preset
|
||||||
|
* This is so that all options override preset values regardless of order in command line */
|
||||||
|
int optind_orig = optind, preset_id = -1;
|
||||||
|
|
||||||
|
static char *iodine_args_short = "46vfDhrX:Y:s:V:c:C:i:j:u:t:d:R:P:w:W:m:M:F:T:O:L:I:";
|
||||||
|
|
||||||
|
while ((choice = getopt_long(argc, argv, iodine_args_short, iodine_args, NULL))) {
|
||||||
|
if (preset_id < 0) {
|
||||||
|
if (choice == -1) {
|
||||||
|
/* reached end of command line and no preset specified - use default */
|
||||||
|
preset_id = 0;
|
||||||
|
} else if (choice == 'Y') {
|
||||||
|
/* find index of preset */
|
||||||
|
if (optarg) {
|
||||||
|
for (int i = 0; i < NUM_CLIENT_PRESETS; i++) {
|
||||||
|
if (toupper(optarg[0] == client_presets[i].short_name)) {
|
||||||
|
preset_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* skip all other options until we find preset */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preset_id < 0) {
|
||||||
|
/* invalid preset or none specified */
|
||||||
|
fprintf(stderr, "Invalid preset or none specified with -Y or --preset! Run 'iodine -h' to see available presets.\n");
|
||||||
|
usage();
|
||||||
|
/* not reached */
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&this, client_presets[preset_id].preset_data, sizeof(struct client_instance));
|
||||||
|
|
||||||
|
/* Reset optind to reparse command line */
|
||||||
|
optind = optind_orig;
|
||||||
|
continue;
|
||||||
|
} else if (choice == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
while ((choice = getopt_long(argc, argv, iodine_args_short, iodine_args, NULL)) != -1) {
|
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case '4':
|
case '4':
|
||||||
nameserv_family = AF_INET;
|
nameserv_family = AF_INET;
|
||||||
@ -318,6 +402,9 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
this.max_timeout_ms = strtod(optarg, NULL) * 1000;
|
this.max_timeout_ms = strtod(optarg, NULL) * 1000;
|
||||||
|
if (this.autodetect_server_timeout) {
|
||||||
|
this.server_timeout_ms = this.max_timeout_ms / 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
this.server_timeout_ms = strtod(optarg, NULL) * 1000;
|
this.server_timeout_ms = strtod(optarg, NULL) * 1000;
|
||||||
@ -346,6 +433,9 @@ main(int argc, char **argv)
|
|||||||
case 'C':
|
case 'C':
|
||||||
this.compression_up = atoi(optarg) & 1;
|
this.compression_up = atoi(optarg) & 1;
|
||||||
break;
|
break;
|
||||||
|
case 'Y':
|
||||||
|
/* Already processed preset: ignore */
|
||||||
|
continue;
|
||||||
case 'X':
|
case 'X':
|
||||||
// TODO implement option for remote host/port to pipe stdin/out
|
// TODO implement option for remote host/port to pipe stdin/out
|
||||||
default:
|
default:
|
||||||
@ -354,6 +444,11 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srand((unsigned) time(NULL));
|
||||||
|
this.rand_seed = (uint16_t) rand();
|
||||||
|
this.chunkid = (uint16_t) rand();
|
||||||
|
this.running = 1;
|
||||||
|
|
||||||
check_superuser(usage);
|
check_superuser(usage);
|
||||||
|
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
@ -404,9 +499,6 @@ main(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove client_set_... functions
|
|
||||||
// client_set_nameservers(nameserv_addrs, nameserv_addrs_len);
|
|
||||||
|
|
||||||
if (this.max_downstream_frag_size < 10 || this.max_downstream_frag_size > MAX_FRAGSIZE) {
|
if (this.max_downstream_frag_size < 10 || this.max_downstream_frag_size > MAX_FRAGSIZE) {
|
||||||
warnx("Use a max frag size between 10 and %d bytes.", MAX_FRAGSIZE);
|
warnx("Use a max frag size between 10 and %d bytes.", MAX_FRAGSIZE);
|
||||||
usage();
|
usage();
|
||||||
@ -431,7 +523,8 @@ main(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.server_timeout_ms < 100 || this.server_timeout_ms >= this.max_timeout_ms) {
|
if ((this.server_timeout_ms < 100 || this.server_timeout_ms >= this.max_timeout_ms)
|
||||||
|
&& !this.autodetect_server_timeout) {
|
||||||
warnx("Server timeout (-i) must be greater than 0.1 sec and less than target interval!");
|
warnx("Server timeout (-i) must be greater than 0.1 sec and less than target interval!");
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
@ -445,14 +538,6 @@ main(int argc, char **argv)
|
|||||||
fprintf(stderr, "Warning: Target interval of >1 second in immediate mode will cause high latency.\n");
|
fprintf(stderr, "Warning: Target interval of >1 second in immediate mode will cause high latency.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// client_set_compression(up_compression, down_compression);
|
|
||||||
// client_set_dnstimeout(target_interval_sec, server_timeout_sec, downstream_timeout_sec, autodetect_server_timeout);
|
|
||||||
// client_set_interval(target_interval_sec * 1000.0, min_interval_ms);
|
|
||||||
// client_set_lazymode(lazymode);
|
|
||||||
// client_set_topdomain(topdomain);
|
|
||||||
// client_set_hostname_maxlen(hostname_maxlen);
|
|
||||||
// client_set_windowsize(up_windowsize, down_windowsize);
|
|
||||||
|
|
||||||
if (username != NULL) {
|
if (username != NULL) {
|
||||||
#ifndef WINDOWS32
|
#ifndef WINDOWS32
|
||||||
if ((pw = getpwnam(username)) == NULL) {
|
if ((pw = getpwnam(username)) == NULL) {
|
||||||
@ -494,8 +579,7 @@ main(int argc, char **argv)
|
|||||||
(a != this.nameserv_addrs_len - 1) ? ", " : "");
|
(a != this.nameserv_addrs_len - 1) ? ", " : "");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
// TODO not pass args to client stuff - use "this" as shared instance
|
if (client_handshake()) {
|
||||||
if (client_handshake(this.dns_fd, this.raw_mode, this.autodetect_frag_size, this.max_downstream_frag_size)) {
|
|
||||||
retval = 1;
|
retval = 1;
|
||||||
goto cleanup2;
|
goto cleanup2;
|
||||||
}
|
}
|
||||||
@ -530,8 +614,7 @@ main(int argc, char **argv)
|
|||||||
if (context != NULL)
|
if (context != NULL)
|
||||||
do_setcon(context);
|
do_setcon(context);
|
||||||
|
|
||||||
// todo don't pass args again.
|
client_tunnel();
|
||||||
client_tunnel(this.tun_fd, this.dns_fd);
|
|
||||||
|
|
||||||
cleanup2:
|
cleanup2:
|
||||||
close_dns(this.dns_fd);
|
close_dns(this.dns_fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user