mirror of
https://github.com/yarrick/iodine.git
synced 2024-11-28 20:45:12 +00:00
Cleaned up client send_packet functions, protocol changes
This commit is contained in:
parent
5ceb6312b4
commit
5233c2ab1e
299
src/client.c
299
src/client.c
@ -426,13 +426,22 @@ send_raw_data(uint8_t *data, size_t datalen)
|
|||||||
static int
|
static int
|
||||||
send_packet(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
|
||||||
|
* cmd becomes first byte of query, followed by hex userid, encoded
|
||||||
|
* data and 3 bytes base32 encoded CMC
|
||||||
* Returns ID of sent query */
|
* Returns ID of sent query */
|
||||||
{
|
{
|
||||||
uint8_t buf[4096];
|
uint8_t buf[512], data_with_cmc[datalen + 2];
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
memcpy(data_with_cmc, data, datalen);
|
||||||
|
*(uint16_t *) (data_with_cmc + datalen) = this.rand_seed;
|
||||||
|
this.rand_seed++;
|
||||||
|
|
||||||
buf[0] = cmd;
|
buf[0] = cmd;
|
||||||
|
buf[1] = this.userid_char;
|
||||||
|
|
||||||
build_hostname(buf, sizeof(buf), data, datalen, this.topdomain, b32, this.hostname_maxlen, 1);
|
build_hostname(buf, sizeof(buf), data_with_cmc, datalen + 2,
|
||||||
|
this.topdomain, b32, this.hostname_maxlen, 2);
|
||||||
|
|
||||||
return send_query(buf);
|
return send_query(buf);
|
||||||
}
|
}
|
||||||
@ -442,27 +451,26 @@ 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) {
|
||||||
uint8_t data[13];
|
uint8_t data[12];
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
/* Build ping header (see doc/proto_xxxxxxxx.txt) */
|
/* Build ping header (see doc/proto_xxxxxxxx.txt) */
|
||||||
data[0] = this.userid;
|
data[0] = ack & 0xFF;
|
||||||
data[1] = ack & 0xFF;
|
|
||||||
|
|
||||||
if (this.outbuf && this.inbuf) {
|
if (this.outbuf && this.inbuf) {
|
||||||
data[2] = this.outbuf->windowsize & 0xff; /* Upstream window size */
|
data[1] = this.outbuf->windowsize & 0xff; /* Upstream window size */
|
||||||
data[3] = this.inbuf->windowsize & 0xff; /* Downstream window size */
|
data[2] = this.inbuf->windowsize & 0xff; /* Downstream window size */
|
||||||
data[4] = this.outbuf->start_seq_id & 0xff; /* Upstream window start */
|
data[3] = this.outbuf->start_seq_id & 0xff; /* Upstream window start */
|
||||||
data[5] = this.inbuf->start_seq_id & 0xff; /* Downstream window start */
|
data[4] = this.inbuf->start_seq_id & 0xff; /* Downstream window start */
|
||||||
}
|
}
|
||||||
|
|
||||||
*(uint16_t *) (data + 6) = htons(this.server_timeout_ms);
|
*(uint16_t *) (data + 5) = htons(this.server_timeout_ms);
|
||||||
*(uint16_t *) (data + 8) = htons(this.downstream_timeout_ms);
|
*(uint16_t *) (data + 7) = htons(this.downstream_timeout_ms);
|
||||||
|
|
||||||
/* update server frag/lazy timeout, ack flag, respond with ping flag */
|
/* update server frag/lazy timeout, ack flag, respond with ping flag */
|
||||||
data[10] = ((set_timeout & 1) << 4) | ((set_timeout & 1) << 3) | ((ack < 0 ? 0 : 1) << 2) | (ping_response & 1);
|
data[9] = ((set_timeout & 1) << 4) | ((set_timeout & 1) << 3) | ((ack < 0 ? 0 : 1) << 2) | (ping_response & 1);
|
||||||
data[11] = (this.rand_seed >> 8) & 0xff;
|
data[10] = (this.rand_seed >> 8) & 0xff;
|
||||||
data[12] = (this.rand_seed >> 0) & 0xff;
|
data[11] = (this.rand_seed >> 0) & 0xff;
|
||||||
this.rand_seed += 1;
|
this.rand_seed += 1;
|
||||||
|
|
||||||
DEBUG(3, " SEND PING: respond %d, ack %d, %s(server %ld ms, downfrag %ld ms), flags %02X",
|
DEBUG(3, " SEND PING: respond %d, ack %d, %s(server %ld ms, downfrag %ld ms), flags %02X",
|
||||||
@ -1309,116 +1317,17 @@ client_tunnel()
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
send_login(char *login, int len)
|
|
||||||
{
|
|
||||||
uint8_t data[19];
|
|
||||||
|
|
||||||
memset(data, 0, sizeof(data));
|
|
||||||
data[0] = this.userid;
|
|
||||||
memcpy(&data[1], login, MIN(len, 16));
|
|
||||||
|
|
||||||
data[17] = (this.rand_seed >> 8) & 0xff;
|
|
||||||
data[18] = (this.rand_seed >> 0) & 0xff;
|
|
||||||
|
|
||||||
this.rand_seed++;
|
|
||||||
|
|
||||||
send_packet('l', data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_fragsize_probe(uint16_t fragsize)
|
|
||||||
{
|
|
||||||
uint8_t probedata[256];
|
|
||||||
uint8_t buf[MAX_FRAGSIZE];
|
|
||||||
uint8_t hdr[3];
|
|
||||||
size_t hdr_len_enc = 6;
|
|
||||||
|
|
||||||
buf[0] = 'r'; /* Probe downstream fragsize packet */
|
|
||||||
|
|
||||||
hdr[0] = this.userid;
|
|
||||||
*(uint16_t *) (hdr + 1) = htons(fragsize);
|
|
||||||
|
|
||||||
b32->encode(buf + 1, &hdr_len_enc, hdr, 3);
|
|
||||||
/* build a large query domain which is random and maximum size,
|
|
||||||
* will also take up maximum space in the return packet */
|
|
||||||
memset(probedata, MAX(1, this.rand_seed & 0xff), sizeof(probedata));
|
|
||||||
probedata[1] = MAX(1, (this.rand_seed >> 8) & 0xff);
|
|
||||||
this.rand_seed++;
|
|
||||||
|
|
||||||
/* Note: must either be same, or larger, than send_chunk() */
|
|
||||||
build_hostname(buf, sizeof(buf), probedata, sizeof(probedata), this.topdomain,
|
|
||||||
this.dataenc, this.hostname_maxlen, 6);
|
|
||||||
|
|
||||||
send_query(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_set_downstream_fragsize(uint16_t fragsize)
|
|
||||||
{
|
|
||||||
uint8_t data[5];
|
|
||||||
|
|
||||||
data[0] = this.userid;
|
|
||||||
*(uint16_t *) (data + 1) = htons(fragsize);
|
|
||||||
data[3] = (this.rand_seed >> 8) & 0xff;
|
|
||||||
data[4] = (this.rand_seed >> 0) & 0xff;
|
|
||||||
|
|
||||||
this.rand_seed++;
|
|
||||||
|
|
||||||
send_packet('n', data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_version(uint32_t version)
|
|
||||||
{
|
|
||||||
uint8_t data[6];
|
|
||||||
|
|
||||||
version = htonl(version);
|
|
||||||
*(uint32_t *) data = version;
|
|
||||||
|
|
||||||
data[4] = (this.rand_seed >> 8) & 0xff;
|
|
||||||
data[5] = (this.rand_seed >> 0) & 0xff;
|
|
||||||
|
|
||||||
this.rand_seed++;
|
|
||||||
|
|
||||||
send_packet('v', data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_ip_request()
|
|
||||||
{
|
|
||||||
uint8_t buf[512] = "i____.";
|
|
||||||
buf[1] = b32_5to8(this.userid);
|
|
||||||
|
|
||||||
buf[2] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
|
||||||
buf[3] = b32_5to8((this.rand_seed >> 5) & 0x1f);
|
|
||||||
buf[4] = b32_5to8((this.rand_seed ) & 0x1f);
|
|
||||||
this.rand_seed++;
|
|
||||||
|
|
||||||
strncat((char *)buf, this.topdomain, 512 - strlen((char *)buf));
|
|
||||||
send_query(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
send_raw_udp_login(int seed)
|
|
||||||
{
|
|
||||||
char buf[16];
|
|
||||||
login_calculate(buf, 16, this.password, seed + 1);
|
|
||||||
|
|
||||||
send_raw((uint8_t *) buf, sizeof(buf), RAW_HDR_CMD_LOGIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_upenctest(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___.";
|
||||||
|
size_t buf_space = 3;
|
||||||
|
|
||||||
buf[1] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
b32->encode((uint8_t *)buf + 1, &buf_space,(uint8_t *)&this.rand_seed, sizeof(this.rand_seed));
|
||||||
buf[2] = b32_5to8((this.rand_seed >> 5) & 0x1f);
|
|
||||||
buf[3] = b32_5to8((this.rand_seed ) & 0x1f);
|
|
||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
|
/* Append test string without changing it */
|
||||||
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));
|
||||||
@ -1426,59 +1335,110 @@ send_upenctest(char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_downenctest(char downenc, int variant, char *s, int slen)
|
send_downenctest(char downenc, int variant)
|
||||||
/* Note: content/handling of s is not defined yet. */
|
|
||||||
{
|
{
|
||||||
char buf[512] = "y_____.";
|
uint8_t buf[512] = "y_____.", hdr[3];
|
||||||
|
|
||||||
buf[1] = tolower(downenc);
|
buf[1] = tolower(downenc);
|
||||||
buf[2] = b32_5to8(variant);
|
|
||||||
|
|
||||||
buf[3] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
hdr[0] = variant;
|
||||||
buf[4] = b32_5to8((this.rand_seed >> 5) & 0x1f);
|
*(uint16_t *) (hdr + 1) = this.rand_seed;
|
||||||
buf[5] = b32_5to8((this.rand_seed ) & 0x1f);
|
|
||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
build_hostname(buf, sizeof(buf), hdr, sizeof(hdr),
|
||||||
send_query((uint8_t *)buf);
|
this.topdomain, b32, this.hostname_maxlen, 2);
|
||||||
|
|
||||||
|
send_query(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_codec_switch(int bits)
|
send_version(uint32_t version)
|
||||||
{
|
{
|
||||||
char buf[512] = "s_____.";
|
uint8_t data[4], buf[512];
|
||||||
buf[1] = b32_5to8(this.userid);
|
|
||||||
buf[2] = b32_5to8(bits);
|
|
||||||
|
|
||||||
buf[3] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
*(uint32_t *) data = htonl(version);
|
||||||
buf[4] = b32_5to8((this.rand_seed >> 5) & 0x1f);
|
|
||||||
buf[5] = b32_5to8((this.rand_seed ) & 0x1f);
|
|
||||||
this.rand_seed++;
|
|
||||||
|
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
buf[0] = 'v';
|
||||||
send_query((uint8_t *)buf);
|
|
||||||
|
build_hostname(buf, sizeof(buf), data, sizeof(data),
|
||||||
|
this.topdomain, b32, this.hostname_maxlen, 1);
|
||||||
|
|
||||||
|
send_query(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_server_options(int lazy, int compression, char denc, char *options)
|
send_login(char *login, int len)
|
||||||
/* Options must be length >=4 */
|
|
||||||
{
|
{
|
||||||
char buf[512] = "oU3___CMC.";
|
send_packet('l', (uint8_t *) login, len);
|
||||||
buf[1] = b32_5to8(this.userid);
|
}
|
||||||
|
|
||||||
options[0] = tolower(denc);
|
static void
|
||||||
options[1] = lazy ? 'l' : 'i';
|
send_fragsize_probe(uint16_t fragsize)
|
||||||
options[2] = compression ? 'c' : 'd';
|
{
|
||||||
options[3] = 0;
|
uint8_t data[256];
|
||||||
strncpy(buf + 3, options, 3);
|
|
||||||
|
|
||||||
buf[6] = b32_5to8((this.rand_seed >> 10) & 0x1f);
|
/* Probe downstream fragsize packet */
|
||||||
buf[7] = b32_5to8((this.rand_seed >> 5) & 0x1f);
|
|
||||||
buf[8] = b32_5to8((this.rand_seed) & 0x1f);
|
/* build a large query domain which is random and maximum size,
|
||||||
|
* will also take up maximum space in the return packet */
|
||||||
|
memset(data, MAX(1, this.rand_seed & 0xff), sizeof(data));
|
||||||
|
|
||||||
|
*(uint16_t *) (data) = htons(fragsize);
|
||||||
this.rand_seed++;
|
this.rand_seed++;
|
||||||
|
|
||||||
strncat(buf, this.topdomain, 512 - strlen(buf));
|
send_packet('r', data, sizeof(data));
|
||||||
send_query((uint8_t *)buf);
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_set_downstream_fragsize(uint16_t fragsize)
|
||||||
|
{
|
||||||
|
uint8_t data[2];
|
||||||
|
*(uint16_t *) data = htons(fragsize);
|
||||||
|
|
||||||
|
send_packet('n', data, sizeof(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_ip_request()
|
||||||
|
{
|
||||||
|
send_packet('i', NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_raw_udp_login(int seed)
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
login_calculate(buf, sizeof(buf), this.password, seed + 1);
|
||||||
|
|
||||||
|
send_raw((uint8_t *) buf, sizeof(buf), RAW_HDR_CMD_LOGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_codec_switch(uint8_t bits)
|
||||||
|
{
|
||||||
|
send_packet('s', &bits, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_server_options(int lazy, int compression, char denc)
|
||||||
|
{
|
||||||
|
uint8_t optflags = 0;
|
||||||
|
|
||||||
|
if (denc == 'T') /* Base32 */
|
||||||
|
optflags |= 1 << 6;
|
||||||
|
else if (denc == 'S') /* Base64 */
|
||||||
|
optflags |= 1 << 5;
|
||||||
|
else if (denc == 'U') /* Base64u */
|
||||||
|
optflags |= 1 << 4;
|
||||||
|
else if (denc == 'V') /* Base128 */
|
||||||
|
optflags |= 1 << 3;
|
||||||
|
else if (denc == 'R') /* Raw */
|
||||||
|
optflags |= 1 << 2;
|
||||||
|
|
||||||
|
optflags |= (compression & 1) << 1;
|
||||||
|
optflags |= lazy & 1;
|
||||||
|
|
||||||
|
send_packet('o', &optflags, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1498,25 +1458,27 @@ handshake_version(int *seed)
|
|||||||
read = handshake_waitdns(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 = ntohl(*(uint32_t *) (in + 4));
|
||||||
((in[5] & 0xff) << 16) |
|
|
||||||
((in[6] & 0xff) << 8) |
|
|
||||||
((in[7] & 0xff)));
|
|
||||||
|
|
||||||
if (strncmp("VACK", (char *)in, 4) == 0) {
|
if (strncmp("VACK", (char *)in, 4) == 0) {
|
||||||
|
/* Payload is login challenge */
|
||||||
*seed = payload;
|
*seed = payload;
|
||||||
this.userid = in[8];
|
this.userid = in[8];
|
||||||
this.userid_char = hex[this.userid & 15];
|
this.userid_char = hex[this.userid & 15];
|
||||||
this.userid_char2 = hex2[this.userid & 15];
|
this.userid_char2 = hex2[this.userid & 15];
|
||||||
|
|
||||||
|
DEBUG(2, "Login challenge: 0x%08x", *seed);
|
||||||
|
|
||||||
fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n",
|
fprintf(stderr, "Version ok, both using protocol v 0x%08x. You are user #%d\n",
|
||||||
PROTOCOL_VERSION, this.userid);
|
PROTOCOL_VERSION, this.userid);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strncmp("VNAK", (char *)in, 4) == 0) {
|
} else if (strncmp("VNAK", (char *)in, 4) == 0) {
|
||||||
|
/* Payload is server version */
|
||||||
warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
|
warnx("You use protocol v 0x%08x, server uses v 0x%08x. Giving up",
|
||||||
PROTOCOL_VERSION, payload);
|
PROTOCOL_VERSION, payload);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (strncmp("VFUL", (char *)in, 4) == 0) {
|
} else if (strncmp("VFUL", (char *)in, 4) == 0) {
|
||||||
|
/* Payload is max number of users on server */
|
||||||
warnx("Server full, all %d slots are taken. Try again later", payload);
|
warnx("Server full, all %d slots are taken. Try again later", payload);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1547,11 +1509,12 @@ handshake_login(int seed)
|
|||||||
send_login(login, 16);
|
send_login(login, 16);
|
||||||
|
|
||||||
read = handshake_waitdns(in, sizeof(in), 'L', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'L', i+1);
|
||||||
|
in[MIN(read, sizeof(in))] = 0; /* Null terminate */
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
int netmask;
|
int netmask;
|
||||||
if (strncmp("LNAK", in, 4) == 0) {
|
if (strncmp("LNAK", in, 4) == 0) {
|
||||||
fprintf(stderr, "Bad this.password\n");
|
fprintf(stderr, "Bad password\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
|
} else if (sscanf(in, "%64[^-]-%64[^-]-%d-%d",
|
||||||
server, client, &mtu, &netmask) == 4) {
|
server, client, &mtu, &netmask) == 4) {
|
||||||
@ -1567,7 +1530,7 @@ handshake_login(int seed)
|
|||||||
errx(4, "Failed to set IP and MTU");
|
errx(4, "Failed to set IP and MTU");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Received bad handshake\n");
|
fprintf(stderr, "Received bad handshake: %.*s\n", read, in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1682,9 +1645,7 @@ handshake_upenctest(char *s)
|
|||||||
char in[4096];
|
char in[4096];
|
||||||
unsigned char *uin = (unsigned char *) in;
|
unsigned char *uin = (unsigned char *) in;
|
||||||
unsigned char *us = (unsigned char *) s;
|
unsigned char *us = (unsigned char *) s;
|
||||||
int i;
|
int i, read, slen;
|
||||||
int read;
|
|
||||||
int slen;
|
|
||||||
|
|
||||||
slen = strlen(s);
|
slen = strlen(s);
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
@ -1850,7 +1811,7 @@ handshake_downenctest(char trycodec)
|
|||||||
|
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_downenctest(trycodec, 1, NULL, 0);
|
send_downenctest(trycodec, 1);
|
||||||
|
|
||||||
read = handshake_waitdns(in, sizeof(in), 'Y', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'Y', i+1);
|
||||||
|
|
||||||
@ -1950,7 +1911,7 @@ handshake_qtypetest(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(trycodec, 1, NULL, 0);
|
send_downenctest(trycodec, 1);
|
||||||
|
|
||||||
read = handshake_waitdns(in, sizeof(in), 'Y', timeout);
|
read = handshake_waitdns(in, sizeof(in), 'Y', timeout);
|
||||||
|
|
||||||
@ -2073,7 +2034,7 @@ handshake_edns0_check()
|
|||||||
|
|
||||||
for (i=0; this.running && i<3 ;i++) {
|
for (i=0; this.running && i<3 ;i++) {
|
||||||
|
|
||||||
send_downenctest(trycodec, 1, NULL, 0);
|
send_downenctest(trycodec, 1);
|
||||||
|
|
||||||
read = handshake_waitdns(in, sizeof(in), 'Y', i+1);
|
read = handshake_waitdns(in, sizeof(in), 'Y', i+1);
|
||||||
|
|
||||||
@ -2162,10 +2123,9 @@ codec_revert:
|
|||||||
void
|
void
|
||||||
handshake_switch_options(int lazy, int compression, char denc)
|
handshake_switch_options(int lazy, int compression, char denc)
|
||||||
{
|
{
|
||||||
char in[4096];
|
char in[100];
|
||||||
int read;
|
int read;
|
||||||
char *dname, *comp_status, *lazy_status;
|
char *dname, *comp_status, *lazy_status;
|
||||||
char opts[4];
|
|
||||||
|
|
||||||
comp_status = compression ? "enabled" : "disabled";
|
comp_status = compression ? "enabled" : "disabled";
|
||||||
|
|
||||||
@ -2185,11 +2145,13 @@ handshake_switch_options(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(lazy, compression, denc, opts);
|
send_server_options(lazy, compression, denc);
|
||||||
|
|
||||||
read = handshake_waitdns(in, sizeof(in) - 1, 'O', i + 1);
|
read = handshake_waitdns(in, sizeof(in) - 1, 'O', i + 1);
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
|
in[read] = 0; /* zero terminate */
|
||||||
|
|
||||||
if (strncmp("BADLEN", in, 6) == 0) {
|
if (strncmp("BADLEN", in, 6) == 0) {
|
||||||
fprintf(stderr, "Server got bad message length.\n");
|
fprintf(stderr, "Server got bad message length.\n");
|
||||||
goto opt_revert;
|
goto opt_revert;
|
||||||
@ -2199,12 +2161,15 @@ handshake_switch_options(int lazy, int compression, char denc)
|
|||||||
} else if (strncmp("BADCODEC", in, 8) == 0) {
|
} else if (strncmp("BADCODEC", in, 8) == 0) {
|
||||||
fprintf(stderr, "Server rejected the selected options.\n");
|
fprintf(stderr, "Server rejected the selected options.\n");
|
||||||
goto opt_revert;
|
goto opt_revert;
|
||||||
}
|
} else if (strcasecmp(dname, in) == 0) {
|
||||||
fprintf(stderr, "Switched server options successfully. (%s)\n", opts);
|
fprintf(stderr, "Switched server options, using downsteam codec %s.\n", in);
|
||||||
this.lazymode = lazy;
|
this.lazymode = lazy;
|
||||||
this.compression_down = compression;
|
this.compression_down = compression;
|
||||||
this.downenc = denc;
|
this.downenc = denc;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Got invalid response. ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Retrying options switch...\n");
|
fprintf(stderr, "Retrying options switch...\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user