Merge 4909486139 into f3a0ce06a9
This commit is contained in:
commit
2ee84c621d
|
|
@ -268,33 +268,43 @@ int decode_hixie(char *src, size_t srclength,
|
||||||
int encode_hybi(u_char const *src, size_t srclength,
|
int encode_hybi(u_char const *src, size_t srclength,
|
||||||
char *target, size_t targsize, unsigned int opcode)
|
char *target, size_t targsize, unsigned int opcode)
|
||||||
{
|
{
|
||||||
unsigned long long b64_sz, len_offset = 1, payload_offset = 2, len = 0;
|
unsigned long long pay_sz, len_offset = 1, payload_offset = 2, len = 0;
|
||||||
|
|
||||||
if ((int)srclength <= 0)
|
if ((int)srclength <= 0)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
b64_sz = ((srclength - 1) / 3) * 4 + 4;
|
if (opcode == 1)
|
||||||
|
pay_sz = ((srclength - 1) / 3) * 4 + 4;
|
||||||
|
if (opcode == 2)
|
||||||
|
pay_sz = srclength;
|
||||||
|
|
||||||
target[0] = (char)(opcode & 0x0F | 0x80);
|
target[0] = (char)(opcode & 0x0F | 0x80);
|
||||||
|
|
||||||
if (b64_sz <= 125) {
|
if (pay_sz <= 125) {
|
||||||
target[1] = (char) b64_sz;
|
target[1] = (char) pay_sz;
|
||||||
payload_offset = 2;
|
payload_offset = 2;
|
||||||
} else if ((b64_sz > 125) && (b64_sz < 65536)) {
|
} else if ((pay_sz > 125) && (pay_sz < 65536)) {
|
||||||
target[1] = (char) 126;
|
target[1] = (char) 126;
|
||||||
*(u_short*)&(target[2]) = htons(b64_sz);
|
*(u_short*)&(target[2]) = htons(pay_sz);
|
||||||
payload_offset = 4;
|
payload_offset = 4;
|
||||||
} else {
|
} else {
|
||||||
handler_emsg("Sending frames larger than 65535 bytes not supported\n");
|
handler_emsg("Sending frames larger than 65535 bytes not supported\n");
|
||||||
return -1;
|
return -1;
|
||||||
//target[1] = (char) 127;
|
//target[1] = (char) 127;
|
||||||
//*(u_long*)&(target[2]) = htonl(b64_sz);
|
//*(u_long*)&(target[2]) = htonl(pay_sz);
|
||||||
//payload_offset = 10;
|
//payload_offset = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opcode == 1) {
|
||||||
len = b64_ntop(src, srclength, target+payload_offset, targsize-payload_offset);
|
len = b64_ntop(src, srclength, target+payload_offset, targsize-payload_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode == 2) {
|
||||||
|
len = srclength;
|
||||||
|
memcpy(target + payload_offset, src, len);
|
||||||
|
}
|
||||||
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return len;
|
return len;
|
||||||
|
|
@ -316,7 +326,7 @@ int decode_hybi(unsigned char *src, size_t srclength,
|
||||||
*left = srclength;
|
*left = srclength;
|
||||||
frame = src;
|
frame = src;
|
||||||
|
|
||||||
//printf("Deocde new frame\n");
|
//printf("Decode new frame\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
// Need at least two bytes of the header
|
// Need at least two bytes of the header
|
||||||
// Find beginning of next frame. First time hdr_length, masked and
|
// Find beginning of next frame. First time hdr_length, masked and
|
||||||
|
|
@ -379,9 +389,11 @@ int decode_hybi(unsigned char *src, size_t srclength,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*opcode == 1) {
|
||||||
// Terminate with a null for base64 decode
|
// Terminate with a null for base64 decode
|
||||||
save_char = payload[payload_length];
|
save_char = payload[payload_length];
|
||||||
payload[payload_length] = '\0';
|
payload[payload_length] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
// unmask the data
|
// unmask the data
|
||||||
mask = payload - 4;
|
mask = payload - 4;
|
||||||
|
|
@ -389,6 +401,7 @@ int decode_hybi(unsigned char *src, size_t srclength,
|
||||||
payload[i] ^= mask[i%4];
|
payload[i] ^= mask[i%4];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*opcode == 1) {
|
||||||
// base64 decode the data
|
// base64 decode the data
|
||||||
len = b64_pton((const char*)payload, target+target_offset, targsize);
|
len = b64_pton((const char*)payload, target+target_offset, targsize);
|
||||||
|
|
||||||
|
|
@ -398,6 +411,13 @@ int decode_hybi(unsigned char *src, size_t srclength,
|
||||||
handler_emsg("Base64 decode error code %d", len);
|
handler_emsg("Base64 decode error code %d", len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*opcode == 2) {
|
||||||
|
len = payload_length;
|
||||||
|
memcpy(target + target_offset, payload, len);
|
||||||
|
}
|
||||||
|
|
||||||
target_offset += len;
|
target_offset += len;
|
||||||
|
|
||||||
//printf(" len %d, raw %s\n", len, frame);
|
//printf(" len %d, raw %s\n", len, frame);
|
||||||
|
|
@ -409,6 +429,7 @@ int decode_hybi(unsigned char *src, size_t srclength,
|
||||||
}
|
}
|
||||||
|
|
||||||
*left = remaining;
|
*left = remaining;
|
||||||
|
//printf(" returning %d, %d left\n", target_offset, *left);
|
||||||
return target_offset;
|
return target_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -481,6 +502,10 @@ int parse_handshake(ws_ctx_t *ws_ctx, char *handshake) {
|
||||||
end = strstr(start, "\r\n");
|
end = strstr(start, "\r\n");
|
||||||
strncpy(headers->protocols, start, end-start);
|
strncpy(headers->protocols, start, end-start);
|
||||||
headers->protocols[end-start] = '\0';
|
headers->protocols[end-start] = '\0';
|
||||||
|
if (strstr(headers->protocols, "binary"))
|
||||||
|
ws_ctx->binary = 1;
|
||||||
|
else
|
||||||
|
ws_ctx->binary = 0;
|
||||||
} else {
|
} else {
|
||||||
// Hixie 75 or 76
|
// Hixie 75 or 76
|
||||||
ws_ctx->hybi = 0;
|
ws_ctx->hybi = 0;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ typedef struct {
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
int hixie;
|
int hixie;
|
||||||
int hybi;
|
int hybi;
|
||||||
|
int binary;
|
||||||
headers_t *headers;
|
headers_t *headers;
|
||||||
char *cin_buf;
|
char *cin_buf;
|
||||||
char *cout_buf;
|
char *cout_buf;
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
||||||
if (FD_ISSET(target, &wlist)) {
|
if (FD_ISSET(target, &wlist)) {
|
||||||
len = tout_end-tout_start;
|
len = tout_end-tout_start;
|
||||||
bytes = send(target, ws_ctx->tout_buf + tout_start, len, 0);
|
bytes = send(target, ws_ctx->tout_buf + tout_start, len, 0);
|
||||||
|
//printf("wrote %d bytes of an intended %d bytes\n", bytes, len);
|
||||||
if (pipe_error) { break; }
|
if (pipe_error) { break; }
|
||||||
if (bytes < 0) {
|
if (bytes < 0) {
|
||||||
handler_emsg("target connection error: %s\n",
|
handler_emsg("target connection error: %s\n",
|
||||||
|
|
@ -149,13 +150,25 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
||||||
bytes = recv(target, ws_ctx->cin_buf, DBUFSIZE , 0);
|
bytes = recv(target, ws_ctx->cin_buf, DBUFSIZE , 0);
|
||||||
if (pipe_error) { break; }
|
if (pipe_error) { break; }
|
||||||
if (bytes <= 0) {
|
if (bytes <= 0) {
|
||||||
|
unsigned char term_buf[48];
|
||||||
|
unsigned char term_rc[2] = {0x0,0};
|
||||||
|
|
||||||
handler_emsg("target closed connection\n");
|
handler_emsg("target closed connection\n");
|
||||||
|
|
||||||
|
bytes = encode_hybi(term_rc, 2, term_buf, sizeof(term_buf), 2);
|
||||||
|
term_buf[0] |= 8;
|
||||||
|
send(ws_ctx->sockfd, term_buf, bytes, 0);
|
||||||
|
shutdown(ws_ctx->sockfd, SHUT_WR);
|
||||||
|
close(target);
|
||||||
|
close(ws_ctx->sockfd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
cout_start = 0;
|
cout_start = 0;
|
||||||
if (ws_ctx->hybi) {
|
if (ws_ctx->hybi) {
|
||||||
cout_end = encode_hybi(ws_ctx->cin_buf, bytes,
|
cout_end = encode_hybi(ws_ctx->cin_buf, bytes,
|
||||||
ws_ctx->cout_buf, BUFSIZE, 1);
|
ws_ctx->cout_buf, BUFSIZE, ws_ctx->binary ? 2 : 1);
|
||||||
} else {
|
} else {
|
||||||
cout_end = encode_hixie(ws_ctx->cin_buf, bytes,
|
cout_end = encode_hixie(ws_ctx->cin_buf, bytes,
|
||||||
ws_ctx->cout_buf, BUFSIZE);
|
ws_ctx->cout_buf, BUFSIZE);
|
||||||
|
|
@ -173,6 +186,7 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
||||||
}
|
}
|
||||||
traffic("{");
|
traffic("{");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FD_ISSET(client, &rlist)) {
|
if (FD_ISSET(client, &rlist)) {
|
||||||
bytes = ws_recv(ws_ctx, ws_ctx->tin_buf + tin_end, BUFSIZE-1);
|
bytes = ws_recv(ws_ctx, ws_ctx->tin_buf + tin_end, BUFSIZE-1);
|
||||||
|
|
@ -181,6 +195,7 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
||||||
handler_emsg("client closed connection\n");
|
handler_emsg("client closed connection\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tin_end += bytes;
|
tin_end += bytes;
|
||||||
/*
|
/*
|
||||||
printf("before decode: ");
|
printf("before decode: ");
|
||||||
|
|
@ -206,13 +221,6 @@ void do_proxy(ws_ctx_t *ws_ctx, int target) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
printf("decoded: ");
|
|
||||||
for (i=0; i< len; i++) {
|
|
||||||
printf("%u,", (unsigned char) *(ws_ctx->tout_buf+i));
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
*/
|
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
handler_emsg("decoding error\n");
|
handler_emsg("decoding error\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue