|
cwebs 0.2.1
WebSocket wire protocol
|
00001 // Copyright (c) 2011-2012, Andre Caron (andre.l.caron@gmail.com) 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // 00011 // Redistributions in binary form must reproduce the above copyright 00012 // notice, this list of conditions and the following disclaimer in the 00013 // documentation and/or other materials provided with the distribution. 00014 // 00015 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00016 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00017 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00018 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00019 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00020 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00021 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00022 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00023 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00025 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 00034 #include "owire.h" 00035 #include <time.h> 00036 #include <stdlib.h> 00037 #include <string.h> 00038 00048 static void _ws_unsafe_random_mask ( struct ws_owire * stream, uint8 mask[4] ) 00049 { 00050 mask[0] = rand() & 0xff; 00051 mask[1] = rand() & 0xff; 00052 mask[2] = rand() & 0xff; 00053 mask[3] = rand() & 0xff; 00054 } 00055 00061 static void _ws_mask ( struct ws_owire * stream ) 00062 { 00063 if ( (stream->data[1]&0x80) != 0 ) { 00064 stream->rand(stream, stream->data+10); 00065 } 00066 } 00067 00073 static void _ws_head ( struct ws_owire * stream ) 00074 { 00075 const uint8 size = (stream->data[1] & 0x7f); 00076 const uint8 usem = (stream->data[1] & 0x80); 00077 // compute prefix size. 00078 uint8 used = 0; 00079 if ( size < 126 ) { 00080 used = 2; 00081 } 00082 if ( size == 126 ) { 00083 used = 4; 00084 } 00085 if ( size == 127 ) { 00086 used = 10; 00087 } 00088 // pack header by moving mask. 00089 if ( usem && (size < 127) ) { 00090 memcpy(stream->data+used, stream->data+10, 4), used += 4; 00091 } 00092 // send packed header. 00093 stream->accept_content(stream, stream->data, used); 00094 } 00095 00110 static uint64 _ws_fail 00111 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00112 { 00113 stream->error = ws_owire_enotready; 00114 return (0); 00115 } 00116 00127 static uint64 _ws_body_1 00128 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00129 { 00130 // don't smear across frames. 00131 size = MIN(size, stream->pass); 00132 // pass all possible data. 00133 stream->accept_content(stream, data, size); 00134 // update cursors. 00135 stream->used += size; 00136 stream->pass -= size; 00137 // prepare for next frame. 00138 if ( stream->pass == 0 ) 00139 { 00140 } 00141 return (size); 00142 } 00143 00154 static uint64 _ws_body_2 00155 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00156 { 00157 uint64 used = 0; 00158 uint8 bufdata[256]; 00159 uint8 bufsize = 0; 00160 // don't smear across frame boundaries. 00161 size = MIN(stream->pass, size); 00162 // start parsing data. 00163 while ( used < size ) 00164 { 00165 // copy butes to buffer and un-mask. 00166 const uint8 *const mask = stream->data+10; 00167 for ( bufsize = 0; (bufsize < size); ++bufsize ) { 00168 bufdata[bufsize] = data[used++] ^ mask[stream->used++%4]; 00169 } 00170 // pass data to stream owner. 00171 stream->accept_content(stream, bufdata, bufsize); 00172 } 00173 // adjust cursors. 00174 stream->pass -= used; 00175 // prepare for next frame. 00176 if ( stream->pass == 0 ) 00177 { 00178 } 00179 return (used); 00180 } 00181 00192 static uint64 _ws_body 00193 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00194 { 00195 return (((stream->data[1] & 0x80)==0)? 00196 _ws_body_1(stream, data, size) : 00197 _ws_body_2(stream, data, size)); 00198 } 00199 00212 static void ws_owire_put_full 00213 ( struct ws_owire * stream, const uint8 * data, uint64 size, uint8 code ) 00214 { 00215 uint64 used = 0; 00216 uint64 part = 0; 00217 ws_owire_new_message(stream); 00218 if ((stream->auto_fragment == 0) || (size == 0)) 00219 { 00220 ws_owire_new_frame(stream, size); 00221 ws_owire_last(stream); 00222 ws_owire_eval(stream, 0); 00223 ws_owire_code(stream, code); 00224 _ws_mask(stream); 00225 _ws_head(stream); 00226 _ws_body(stream, data, size); 00227 ws_owire_end_frame(stream); 00228 } 00229 else 00230 { 00231 while ( used < size ) 00232 { 00233 part = MIN(size-used, stream->auto_fragment); 00234 ws_owire_new_frame(stream, part); 00235 { 00236 if ( (used+part) >= size ) { 00237 ws_owire_last(stream); 00238 } 00239 ws_owire_eval(stream, 0); 00240 if ( used == 0 ) { 00241 ws_owire_code(stream, code); 00242 } else { 00243 ws_owire_code(stream, 0); 00244 } 00245 if ( stream->auto_mask ) { 00246 ws_owire_mask(stream); 00247 } 00248 _ws_mask(stream); 00249 _ws_head(stream); 00250 used += _ws_body(stream, data+used, part); 00251 } 00252 ws_owire_end_frame(stream); 00253 } 00254 } 00255 ws_owire_end_message(stream); 00256 } 00257 00258 void ws_owire_init ( struct ws_owire * stream ) 00259 { 00260 stream->accept_content = 0; 00261 stream->prng = 0; 00262 stream->rand = &_ws_unsafe_random_mask; 00263 stream->baton = 0; 00264 stream->auto_fragment = 0; 00265 stream->auto_mask = 0; 00266 stream->state = &_ws_fail; 00267 stream->pass = 0; 00268 } 00269 00270 void ws_owire_new_message ( struct ws_owire * stream ) 00271 { 00272 memset(stream->data, 0, 14); 00273 stream->state = &_ws_fail; 00274 stream->pass = 0; 00275 } 00276 00277 void ws_owire_end_message ( struct ws_owire * stream ) 00278 { 00279 memset(stream->data, 0, 14); 00280 stream->state = &_ws_fail; 00281 stream->pass = 0; 00282 } 00283 00284 void ws_owire_new_frame ( struct ws_owire * stream, uint64 size ) 00285 { 00286 memset(stream->data, 0, 14); 00287 stream->state = &_ws_fail; 00288 stream->pass = size; 00289 if ( size < 126 ) 00290 { 00291 stream->data[1] &= 0x7f; 00292 stream->data[1] |= size; 00293 } 00294 else if ( size < 65537 ) 00295 { 00296 stream->data[1] &= 0x7f; 00297 stream->data[1] |= 126; 00298 stream->data[2] = ((size >> 8) & 0xff); 00299 stream->data[3] = ((size >> 0) & 0xff); 00300 } 00301 else 00302 { 00303 stream->data[1] &= 0x7f; 00304 stream->data[1] |= 127; 00305 stream->data[2] = ((size >> 56) & 0xff); 00306 stream->data[3] = ((size >> 48) & 0xff); 00307 stream->data[4] = ((size >> 40) & 0xff); 00308 stream->data[5] = ((size >> 32) & 0xff); 00309 stream->data[6] = ((size >> 24) & 0xff); 00310 stream->data[7] = ((size >> 16) & 0xff); 00311 stream->data[8] = ((size >> 8) & 0xff); 00312 stream->data[9] = ((size >> 0) & 0xff); 00313 } 00314 } 00315 00316 void ws_owire_end_frame ( struct ws_owire * stream ) 00317 { 00318 memset(stream->data, 0, 14); 00319 stream->state = &_ws_fail; 00320 stream->pass = 0; 00321 } 00322 00323 void ws_owire_last ( struct ws_owire * stream ) 00324 { 00325 // set bit 8. 00326 stream->data[0] |= 0x80; 00327 } 00328 00329 void ws_owire_eval ( struct ws_owire * stream, uint8 eval ) 00330 { 00331 // clear, then set bits 5-7. 00332 stream->data[0] &= 0xf1; 00333 stream->data[0] |= ((eval & 0x07) << 4); 00334 } 00335 00336 void ws_owire_code ( struct ws_owire * stream, uint8 code ) 00337 { 00338 // clear, then set bits 5-7. 00339 stream->data[0] &= 0xf0; 00340 stream->data[0] |= (code & 0x0f); 00341 } 00342 00343 void ws_owire_mask ( struct ws_owire * stream ) 00344 { 00345 // set bit 8. 00346 stream->data[1] |= 0x80; 00347 } 00348 00349 uint64 ws_owire_feed 00350 ( struct ws_owire * stream, const void * data, uint64 size ) 00351 { 00352 return (stream->state(stream, static_cast<const uint8*>(data), size)); 00353 } 00354 00355 void ws_owire_put_text 00356 ( struct ws_owire * stream, const void * data, uint64 size ) 00357 { 00358 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x01); 00359 } 00360 00361 void ws_owire_put_data 00362 ( struct ws_owire * stream, const void * data, uint64 size ) 00363 { 00364 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x02); 00365 } 00366 00367 void ws_owire_put_kill 00368 ( struct ws_owire * stream, const void * data, uint64 size ) 00369 { 00370 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x08); 00371 } 00372 00373 void ws_owire_put_ping 00374 ( struct ws_owire * stream, const void * data, uint64 size ) 00375 { 00376 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x09); 00377 } 00378 00379 void ws_owire_put_pong 00380 ( struct ws_owire * stream, const void * data, uint64 size ) 00381 { 00382 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x0a); 00383 } 00384