Skip to content

Commit 04b2dbb

Browse files
committed
fixed malformed close frames
1 parent 2c1af97 commit 04b2dbb

File tree

1,051 files changed

+71780
-8246
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,051 files changed

+71780
-8246
lines changed

.cproject

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@
3030
<option id="gnu.c.compiler.option.misc.other.835723838" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
3131
<option id="gnu.c.compiler.option.misc.verbose.1371801120" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" value="true" valueType="boolean"/>
3232
<option id="gnu.c.compiler.option.misc.ansi.183199256" name="Support ANSI programs (-ansi)" superClass="gnu.c.compiler.option.misc.ansi" value="false" valueType="boolean"/>
33-
<option id="gnu.c.compiler.option.include.paths.224587811" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath"/>
33+
<option id="gnu.c.compiler.option.include.paths.224587811" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths"/>
3434
<option id="gnu.c.compiler.option.include.files.1297155078" name="Include files (-include)" superClass="gnu.c.compiler.option.include.files"/>
35+
<option id="gnu.c.compiler.option.dialect.std.981082959" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
3536
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.671860280" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
3637
</tool>
3738
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.928242729" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">

src/cwebsocket/client.c

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ void cwebsocket_client_listen(cwebsocket_client *websocket) {
429429
void *cwebsocket_client_onmessage_thread(void *ptr) {
430430
cwebsocket_client_thread_args *args = (cwebsocket_client_thread_args *)ptr;
431431
cwebsocket_client_onmessage(args->socket, args->message);
432-
free(args->message->payload);
432+
//free(args->message->payload);
433433
free(args->message);
434434
free(ptr);
435435
return NULL;
@@ -452,26 +452,24 @@ int cwebsocket_client_send_control_frame(cwebsocket_client *websocket, opcode co
452452
control_frame[4] = masking_key[2];
453453
control_frame[5] = masking_key[3];
454454
if(code & CLOSE) {
455-
uint16_t close_code = 0;
455+
uint16_t close_code = 1000;
456456
if(payload_len >= 2) {
457-
control_frame[6] = payload[0];
458-
control_frame[7] = payload[1];
459-
close_code = (control_frame[6] << 8) + control_frame[7];
460457
if(payload_len > 2) {
461-
char parsed_payload[payload_len-2];
462-
memcpy(parsed_payload, &payload[2], payload_len-2);
463-
parsed_payload[payload_len-2] = '\0';
458+
char parsed_payload[payload_len];
459+
memcpy(parsed_payload, &payload[0], payload_len);
460+
parsed_payload[payload_len] = '\0';
461+
close_code = (control_frame[6] << 8) + control_frame[7];
464462
int i;
465463
for(i=0; i<payload_len; i++) {
466-
control_frame[8+i] = (parsed_payload[i] ^ masking_key[i % 4]) & 0xff;
464+
control_frame[6+i] = (parsed_payload[i] ^ masking_key[i % 4]) & 0xff;
467465
}
468466
syslog(LOG_DEBUG, "cwebsocket_client_send_control_frame: opcode=%#04x, frame_type=%s, payload_len=%i, code=%i, payload=%s",
469467
code, frame_type, payload_len, close_code, parsed_payload);
470468
}
471469
else {
472470
syslog(LOG_DEBUG, "cwebsocket_client_send_control_frame: opcode=%#04x, frame_type=%s, payload_len=%i, code=%i, payload=(null)",
473471
code, frame_type, payload_len, close_code);
474-
}
472+
}
475473
}
476474
else {
477475
syslog(LOG_DEBUG, "cwebsocket_client_send_control_frame: opcode=%#04x, frame_type=%s, payload_len=%i, code=%i, payload=(null)",
@@ -522,10 +520,10 @@ int cwebsocket_client_read_data(cwebsocket_client *websocket) {
522520
while(bytes_read < frame_size && (websocket->state & WEBSOCKET_STATE_OPEN)) {
523521

524522
if(bytes_read >= CWS_DATA_BUFFER_MAX) {
525-
syslog(LOG_ERR, "cwebsocket_client_read_data: frame too large. RECEIVE_BUFFER_MAX = %i bytes. bytes_read=%i, header_length=%i",
526-
CWS_DATA_BUFFER_MAX, bytes_read, header_length);
527-
cwebsocket_client_close(websocket, 1009, "frame too large");
528-
return -1;
523+
syslog(LOG_ERR, "cwebsocket_client_read_data: frame too large. RECEIVE_BUFFER_MAX = %i bytes. bytes_read=%i, header_length=%i",
524+
CWS_DATA_BUFFER_MAX, bytes_read, header_length);
525+
cwebsocket_client_close(websocket, 1009, "frame too large");
526+
return -1;
529527
}
530528

531529
ssize_t byte = cwebsocket_client_read(websocket, data+bytes_read, 1);
@@ -596,7 +594,7 @@ int cwebsocket_client_read_data(cwebsocket_client *websocket) {
596594

597595
if(frame.fin && frame.opcode == TEXT_FRAME) {
598596

599-
char *payload = malloc(sizeof(char) * payload_length);
597+
char *payload = malloc(sizeof(char) * payload_length+1);
600598
if(payload == NULL) {
601599
perror("out of memory");
602600
exit(-1);
@@ -625,13 +623,7 @@ int cwebsocket_client_read_data(cwebsocket_client *websocket) {
625623
memset(message, 0, sizeof(cwebsocket_message));
626624
message->opcode = frame.opcode;
627625
message->payload_len = frame.payload_len;
628-
message->payload = malloc(sizeof(char) * (payload_length+1));
629-
if(message->payload == NULL) {
630-
perror("out of memory");
631-
exit(-1);
632-
}
633-
strncpy(message->payload, payload, payload_length+1);
634-
free(payload);
626+
message->payload = payload;
635627

636628
cwebsocket_client_thread_args *args = malloc(sizeof(cwebsocket_client_thread_args));
637629
if(args == NULL) {
@@ -652,15 +644,9 @@ int cwebsocket_client_read_data(cwebsocket_client *websocket) {
652644
cwebsocket_message message = {0};
653645
message.opcode = frame.opcode;
654646
message.payload_len = frame.payload_len;
655-
message.payload = malloc(sizeof(char) * (payload_length+1));
656-
if(message.payload == NULL) {
657-
perror("out of memory");
658-
exit(-1);
659-
}
660-
strncpy(message.payload, payload, payload_length+1);
647+
message.payload = payload;
661648
cwebsocket_client_onmessage(websocket, &message);
662-
free(payload);
663-
free(message.payload);
649+
//free(payload);
664650
return bytes_read;
665651
#endif
666652
}
@@ -672,18 +658,25 @@ int cwebsocket_client_read_data(cwebsocket_client *websocket) {
672658

673659
syslog(LOG_DEBUG, "cwebsocket_client_read_data: received BINARY payload. bytes=%zu", payload_length);
674660

675-
char payload[payload_length];
661+
char *payload = malloc(sizeof(char) * payload_length);
662+
if(payload == NULL) {
663+
perror("out of memory");
664+
exit(-1);
665+
}
676666
memcpy(payload, &data[header_length], payload_length);
677667
free(data);
678668

679669
if(websocket->subprotocol->onmessage != NULL) {
680670

681671
#ifdef ENABLE_THREADS
682672
cwebsocket_message *message = malloc(sizeof(cwebsocket_message));
673+
if(message == NULL) {
674+
perror("out of memory");
675+
exit(-1);
676+
}
683677
message->opcode = frame.opcode;
684678
message->payload_len = frame.payload_len;
685-
message->payload = malloc(sizeof(char) * payload_length);
686-
memcpy(message->payload, payload, payload_length);
679+
message->payload = payload;
687680

688681
cwebsocket_client_thread_args *args = malloc(sizeof(cwebsocket_client_thread_args));
689682
args->socket = websocket;
@@ -701,6 +694,7 @@ int cwebsocket_client_read_data(cwebsocket_client *websocket) {
701694
message.payload_len = frame.payload_len;
702695
message.payload = payload;
703696
websocket->subprotocol->onmessage(websocket, &message);
697+
free(payload);
704698
return bytes_read;
705699
#endif
706700
}

src/cwebsocket/subprotocol/echo/echo_client.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ void cwebsocket_subprotocol_echo_client_onopen(void *websocket) {
3131

3232
void cwebsocket_subprotocol_echo_client_onmessage(void *websocket, cwebsocket_message *message) {
3333
cwebsocket_client *client = (cwebsocket_client *)websocket;
34-
syslog(LOG_DEBUG, "cwebsocket_subprotocol_echo_client_onmessage: fd=%i, opcode=%#04x, payload_len=%zu, actual_payload_len=%zd, payload=%s\n",
35-
client->fd, message->opcode, message->payload_len, strlen(message->payload), message->payload);
34+
syslog(LOG_DEBUG, "cwebsocket_subprotocol_echo_client_onmessage: fd=%i, opcode=%#04x, payload_len=%zu, payload=%s\n",
35+
client->fd, message->opcode, message->payload_len, message->payload);
3636
}
3737

3838
void cwebsocket_subprotocol_echo_client_onclose(void *websocket, int code, const char *reason) {

src/cwebsocket/utf8.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ int utf8_count_code_points(uint8_t* s, size_t* count) {
1212
return state != UTF8_ACCEPT;
1313
}
1414

15-
uint32_t inline utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
15+
uint32_t utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
1616

1717
uint32_t type = utf8d[byte];
1818
*codep = (*state != UTF8_ACCEPT) ?

src/cwebsocket/utf8.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static const uint8_t utf8d[] = {
3232
};
3333

3434
int utf8_count_code_points(uint8_t* s, size_t* count);
35-
uint32_t inline utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte);
35+
uint32_t utf8_decode(uint32_t* state, uint32_t* codep, uint32_t byte);
3636

3737
#ifdef __cplusplus
3838
}

src/websocket-server.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "cwebsocket/server.h"
2727
#include "cwebsocket/subprotocol/echo/echo_server.h"
2828

29-
void signal_handler(int sig) {
29+
void server_signal_handler(int sig) {
3030
switch(sig) {
3131
case SIGHUP:
3232
syslog(LOG_DEBUG, "Received SIGHUP signal");
@@ -44,7 +44,7 @@ void signal_handler(int sig) {
4444
}
4545
}
4646

47-
void print_program_header() {
47+
void server_print_program_header() {
4848
printf("\n");
4949
printf(" ______ ______ _____ \n");
5050
printf(" _________ _________ /_______________________ /________ /_\n");
@@ -58,14 +58,14 @@ void print_program_header() {
5858
printf("\n");
5959
}
6060

61-
void print_program_usage(const char *progname) {
61+
void server_print_program_usage(const char *progname) {
6262
fprintf(stderr, "usage: %s -p 8080\n\n", progname);
6363
exit(0);
6464
}
6565

66-
int main(int argc, char **argv) {
66+
int server_main(int argc, char **argv) {
6767

68-
print_program_header();
68+
server_print_program_header();
6969

7070
int cores = 1;
7171
int port = 8080;
@@ -108,7 +108,7 @@ int main(int argc, char **argv) {
108108
sigprocmask(SIG_BLOCK, &newSigSet, NULL); /* Block the above specified signals */
109109

110110
// Set up a signal handler
111-
newSigAction.sa_handler = signal_handler;
111+
newSigAction.sa_handler = server_signal_handler;
112112
sigemptyset(&newSigAction.sa_mask);
113113
newSigAction.sa_flags = 0;
114114

src/websocket-testsuite.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ cwebsocket_subprotocol* autobahn_testsuite_new() {
7878
return protocol;
7979
}
8080

81-
int main_exit(int exit_status) {
81+
int testsuite_main_exit(int exit_status) {
8282
syslog(LOG_DEBUG, "exiting cwebsocket");
8383
closelog();
8484
return exit_status;
8585
}
8686

87-
void print_program_header() {
87+
void testsuite_print_program_header() {
8888
printf("\n");
8989
printf(" ______ ______ _____ \n");
9090
printf(" _________ _________ /_______________________ /________ /_\n");
@@ -98,9 +98,9 @@ void print_program_header() {
9898
printf("\n");
9999
}
100100

101-
int main(int argc, char **argv) {
101+
int testsuite_main(int argc, char **argv) {
102102

103-
print_program_header();
103+
testsuite_print_program_header();
104104

105105
setlogmask(LOG_UPTO(LOG_DEBUG));
106106
openlog("cwebsocket", LOG_CONS | LOG_PERROR, LOG_USER);

test/autobahn/reports/client/cwebsocket_0_1a_case_10_1_1.html

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@
202202
<center><a href="http://autobahn.ws/testsuite" title="Autobahn WebSockets Testsuite"><img src="http://autobahn.ws/static/img/ws_protocol_test_report.png" border="0" width="820" height="46" alt="Autobahn WebSockets Testsuite Report"></img></a></center>
203203
<center><a href="http://autobahn.ws" title="Autobahn WebSockets"> <img src="http://autobahn.ws/static/img/ws_protocol_test_report_autobahn.png" border="0" width="300" height="68" alt="Autobahn WebSockets"> </img></a></center>
204204
<br/>
205-
<p class="case case_failed">cwebsocket/0.1a - <span style="font-size: 1.3em;"><b>Case 10.1.1</b></span> : Fail - <span style="font-size: 0.9em;"><b>5</b> ms @ 2014-02-27T23:03:58Z</a></p>
205+
<p class="case case_failed">cwebsocket/0.1a - <span style="font-size: 1.3em;"><b>Case 10.1.1</b></span> : Fail - <span style="font-size: 0.9em;"><b>4</b> ms @ 2014-03-31T00:42:24Z</a></p>
206206
<p class="case_text_block case_desc"><b>Case Description</b><br/><br/>Send text message with payload of length 65536 auto-fragmented with <b>autoFragmentSize = 1300</b>.</p>
207207
<p class="case_text_block case_expect"><b>Case Expectation</b><br/><br/>Receive echo'ed text message (with payload as sent and transmitted frame counts as expected). Clean close with normal code.</p>
208208

@@ -211,20 +211,20 @@
211211
<i>Expected:</i><br/><span class="case_pickle">{'OK': [('message', u'**************************************************************** ...', False)]}</span><br/><br/>
212212
<i>Observed:</i><br><span class="case_pickle">[]</span>
213213
</p>
214-
<p class="case_text_block case_closing_beh"><b>Case Closing Behavior</b><br/><br/>The close code should have been 1000 or empty (WRONG CODE)</p>
214+
<p class="case_text_block case_closing_beh"><b>Case Closing Behavior</b><br/><br/>The spec requires the connection to be failed cleanly here (UNCLEAN)</p>
215215
<br/><hr/>
216216
<h2>Opening Handshake</h2>
217217
<pre class="http_dump">GET /runCase?case=305&agent=cwebsocket/0.1a HTTP/1.1
218218
Host: localhost:9001
219219
Upgrade: WebSocket
220220
Connection: Upgrade
221-
Sec-WebSocket-Key: MmpHQlpqU2NsRWpCVUlNcw==
221+
Sec-WebSocket-Key: WkdBVGF5YW9icjFiN3hTMQ==
222222
Sec-WebSocket-Version: 13</pre>
223223
<pre class="http_dump">HTTP/1.1 101 Switching Protocols
224-
Server: AutobahnTestSuite/0.6.0-0.8.1
224+
Server: AutobahnTestSuite/0.6.1-0.8.6
225225
Upgrade: WebSocket
226226
Connection: Upgrade
227-
Sec-WebSocket-Accept: ZbN2arqgIdQ8N8gsKRSpDce44yw=</pre>
227+
Sec-WebSocket-Accept: EN7kZS9++YEYwZvTTaz8P9C9raM=</pre>
228228
<br/><hr/>
229229
<h2>Closing Behavior</h2>
230230
<table>
@@ -233,15 +233,15 @@ <h2>Closing Behavior</h2>
233233
<tr class="stats_row"><td>closedByMe</td><td class="left">True</td><td class="left">True, iff I have initiated closing handshake (that is, did send close first).</td></tr>
234234
<tr class="stats_row"><td>failedByMe</td><td class="left">True</td><td class="left">True, iff I have failed the WS connection (i.e. due to protocol error). Failing can be either by initiating closing handshake or brutal drop TCP.</td></tr>
235235
<tr class="stats_row"><td>droppedByMe</td><td class="left">True</td><td class="left">True, iff I dropped the TCP connection.</td></tr>
236-
<tr class="stats_row"><td>wasClean</td><td class="left">True</td><td class="left">True, iff full WebSockets closing handshake was performed (close frame sent and received) _and_ the server dropped the TCP (which is its responsibility).</td></tr>
236+
<tr class="stats_row"><td>wasClean</td><td class="left">False</td><td class="left">True, iff full WebSockets closing handshake was performed (close frame sent and received) _and_ the server dropped the TCP (which is its responsibility).</td></tr>
237237
<tr class="stats_row"><td>wasNotCleanReason</td><td class="left">None</td><td class="left">When wasClean == False, the reason what happened.</td></tr>
238238
<tr class="stats_row"><td>wasServerConnectionDropTimeout</td><td class="left">False</td><td class="left">When we are a client, and we expected the server to drop the TCP, but that didn't happen in time, this gets True.</td></tr>
239239
<tr class="stats_row"><td>wasOpenHandshakeTimeout</td><td class="left">False</td><td class="left">When performing the opening handshake, but the peer did not finish in time, this gets True.</td></tr>
240240
<tr class="stats_row"><td>wasCloseHandshakeTimeout</td><td class="left">False</td><td class="left">When we initiated a closing handshake, but the peer did not respond in time, this gets True.</td></tr>
241241
<tr class="stats_row"><td>localCloseCode</td><td class="left">1002</td><td class="left">The close code I sent in close frame (if any).</td></tr>
242-
<tr class="stats_row"><td>localCloseReason</td><td class="left">invalid close code 34484</td><td class="left">The close reason I sent in close frame (if any).</td></tr>
243-
<tr class="stats_row"><td>remoteCloseCode</td><td class="left">34484</td><td class="left">The close code the peer sent me in close frame (if any).</td></tr>
244-
<tr class="stats_row"><td>remoteCloseReason</td><td class="left">34"4('$5a$/"4!1>3%$5a>12.5$kaa9ap</td><td class="left">The close reason the peer sent me in close frame (if any).</td></tr>
242+
<tr class="stats_row"><td>localCloseReason</td><td class="left">invalid close code 27418</td><td class="left">The close reason I sent in close frame (if any).</td></tr>
243+
<tr class="stats_row"><td>remoteCloseCode</td><td class="left">27418</td><td class="left">The close code the peer sent me in close frame (if any).</td></tr>
244+
<tr class="stats_row"><td>remoteCloseReason</td><td class="left">None</td><td class="left">The close reason the peer sent me in close frame (if any).</td></tr>
245245
</table> <br/><hr/>
246246
<h2>Wire Statistics</h2>
247247
<h3>Octets Received by Chop Size</h3>
@@ -486,12 +486,12 @@ <h2>Wire Log</h2>
486486
<pre class="wirelog_tx_octets">103 TX OCTETS: 807e02182a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a</pre>
487487
<pre class="wirelog_tx_octets"> 2a2a2a2a2a2a2a2a2a2a2a2a2a2a ...</pre>
488488
<pre class="wirelog_kill_after">104 FAIL CONNECTION AFTER 10.000000 sec</pre>
489-
<pre class="wirelog_rx_octets">105 RX OCTETS: 88a3855ec40f03eaf73ba76aec28a16ba52baa7cf02eb460f72aa16ba531b46cea3aa135a56ebc3fb4</pre>
490-
<pre class="wirelog_rx_frame">106 RX FRAME : OPCODE=8, FIN=True, RSV=0, PAYLOAD-LEN=35, MASKED=True, MASK=3835356563343066</pre>
491-
<pre class="wirelog_rx_frame"> 0x86b4333422342827243561242f223421313e33252435613e31322e35246b6161396170</pre>
489+
<pre class="wirelog_rx_octets">105 RX OCTETS: 88a368f0b93803ea1a95da5d0186dc5c4885d74b1d80c9571a84dc5c489fc95b0794dc0248c0c10859</pre>
490+
<pre class="wirelog_rx_frame">106 RX FRAME : OPCODE=8, FIN=True, RSV=0, PAYLOAD-LEN=35, MASKED=True, MASK=3638663062393338</pre>
491+
<pre class="wirelog_rx_frame"> 0x6b1aa3adb2adb8beb4acf1bdbfbba4b8a1a7a3bcb4acf1a7a1abbeacb4f2f1f8a9f8e0</pre>
492492
<pre class="wirelog_tx_frame">107 TX FRAME : OPCODE=8, FIN=True, RSV=0, PAYLOAD-LEN=26, MASK=None, PAYLOAD-REPEAT-LEN=None, CHOPSIZE=None, SYNC=False</pre>
493-
<pre class="wirelog_tx_frame"> 0x03ea696e76616c696420636c6f736520636f6465203334343834</pre>
494-
<pre class="wirelog_tx_octets">108 TX OCTETS: 881a03ea696e76616c696420636c6f736520636f6465203334343834</pre>
493+
<pre class="wirelog_tx_frame"> 0x03ea696e76616c696420636c6f736520636f6465203237343138</pre>
494+
<pre class="wirelog_tx_octets">108 TX OCTETS: 881a03ea696e76616c696420636c6f736520636f6465203237343138</pre>
495495
<pre class="wirelog_tcp_closed_by_me">109 TCP DROPPED BY ME</pre>
496496
</div>
497497
<br/><hr/>

0 commit comments

Comments
 (0)