|
cwebs 0.2
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 00039 // 00040 // horrible random number generator. used if nothing better is provided. 00041 // 00042 static void _ws_unsafe_random_mask ( struct ws_owire * stream, uint8 mask[4] ) 00043 { 00044 mask[0] = rand() & 0xff; 00045 mask[1] = rand() & 0xff; 00046 mask[2] = rand() & 0xff; 00047 mask[3] = rand() & 0xff; 00048 } 00049 00050 static void _ws_copy ( uint8 * lhs, const uint8 * rhs, uint8 size ) 00051 { 00052 uint8 used = 0; 00053 for ( ; (used < size); ++used ) { 00054 *lhs++ = *rhs++; 00055 } 00056 } 00057 00058 // 00059 // generate frame mask, if required. 00060 // 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 00068 // 00069 // emit frame header. 00070 // 00071 static void _ws_head ( struct ws_owire * stream ) 00072 { 00073 const uint8 size = (stream->data[1] & 0x7f); 00074 const uint8 usem = (stream->data[1] & 0x80); 00075 // compute prefix size. 00076 uint8 used = 0; 00077 if ( size < 126 ) { 00078 used = 2; 00079 } 00080 if ( size == 126 ) { 00081 used = 4; 00082 } 00083 if ( size == 127 ) { 00084 used = 10; 00085 } 00086 // pack header by moving mask. 00087 if ( usem && (size < 127) ) { 00088 memcpy(stream->data+used, stream->data+10, 4), used += 4; 00089 } 00090 // send packed header. 00091 stream->accept_content(stream, stream->data, used); 00092 } 00093 00094 // 00095 // fail emit frame content, not ready yet. 00096 // 00097 static uint64 _ws_fail 00098 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00099 { 00100 stream->error = ws_owire_enotready; 00101 return (0); 00102 } 00103 00104 // 00105 // emit frame content. 00106 // 00107 static uint64 _ws_body_1 00108 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00109 { 00110 // don't smear across frames. 00111 size = MIN(size, stream->pass); 00112 // pass all possible data. 00113 stream->accept_content(stream, data, size); 00114 // update cursors. 00115 stream->used += size; 00116 stream->pass -= size; 00117 // prepare for next frame. 00118 if ( stream->pass == 0 ) 00119 { 00120 } 00121 return (size); 00122 } 00123 00124 // 00125 // mask, then emit frame content. 00126 // 00127 static uint64 _ws_body_2 00128 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00129 { 00130 uint64 used = 0; 00131 uint8 bufdata[256]; 00132 uint8 bufsize = 0; 00133 // don't smear across frame boundaries. 00134 size = MIN(stream->pass, size); 00135 // start parsing data. 00136 while ( used < size ) 00137 { 00138 // copy butes to buffer and un-mask. 00139 const uint8 *const mask = stream->data+10; 00140 for ( bufsize = 0; (bufsize < size); ++bufsize ) { 00141 bufdata[bufsize] = data[used++] ^ mask[stream->used++%4]; 00142 } 00143 // pass data to stream owner. 00144 stream->accept_content(stream, bufdata, bufsize); 00145 } 00146 // adjust cursors. 00147 stream->pass -= used; 00148 // prepare for next frame. 00149 if ( stream->pass == 0 ) 00150 { 00151 } 00152 return (used); 00153 } 00154 00155 // 00156 // take care of masking if required, then ship the data. 00157 // 00158 static uint64 _ws_body 00159 ( struct ws_owire * stream, const uint8 * data, uint64 size ) 00160 { 00161 return (((stream->data[1] & 0x80)==0)? 00162 _ws_body_1(stream, data, size) : 00163 _ws_body_2(stream, data, size)); 00164 } 00165 00166 // 00167 // emit full message (optionally break it up). 00168 // 00169 static void ws_owire_put_full 00170 ( struct ws_owire * stream, const uint8 * data, uint64 size, uint8 code ) 00171 { 00172 uint64 used = 0; 00173 uint64 part = 0; 00174 ws_owire_new_message(stream); 00175 if ((stream->auto_fragment == 0) || (size == 0)) 00176 { 00177 ws_owire_new_frame(stream, size); 00178 ws_owire_last(stream); 00179 ws_owire_eval(stream, 0); 00180 ws_owire_code(stream, code); 00181 _ws_mask(stream); 00182 _ws_head(stream); 00183 _ws_body(stream, data, size); 00184 ws_owire_end_frame(stream); 00185 } 00186 else 00187 { 00188 while ( used < size ) 00189 { 00190 part = MIN(size-used, stream->auto_fragment); 00191 ws_owire_new_frame(stream, part); 00192 { 00193 if ( (used+part) >= size ) { 00194 ws_owire_last(stream); 00195 } 00196 ws_owire_eval(stream, 0); 00197 if ( used == 0 ) { 00198 ws_owire_code(stream, code); 00199 } else { 00200 ws_owire_code(stream, 0); 00201 } 00202 if ( stream->auto_mask ) { 00203 ws_owire_mask(stream); 00204 } 00205 _ws_mask(stream); 00206 _ws_head(stream); 00207 used += _ws_body(stream, data+used, part); 00208 } 00209 ws_owire_end_frame(stream); 00210 } 00211 } 00212 ws_owire_end_message(stream); 00213 } 00214 00215 void ws_owire_init ( struct ws_owire * stream ) 00216 { 00217 stream->accept_content = 0; 00218 stream->prng = 0; 00219 stream->rand = &_ws_unsafe_random_mask; 00220 stream->baton = 0; 00221 stream->auto_fragment = 0; 00222 stream->auto_mask = 0; 00223 stream->state = &_ws_fail; 00224 stream->pass = 0; 00225 } 00226 00227 void ws_owire_new_message ( struct ws_owire * stream ) 00228 { 00229 memset(stream->data, 0, 14); 00230 stream->state = &_ws_fail; 00231 stream->pass = 0; 00232 } 00233 00234 void ws_owire_end_message ( struct ws_owire * stream ) 00235 { 00236 memset(stream->data, 0, 14); 00237 stream->state = &_ws_fail; 00238 stream->pass = 0; 00239 } 00240 00241 void ws_owire_new_frame ( struct ws_owire * stream, uint64 size ) 00242 { 00243 memset(stream->data, 0, 14); 00244 stream->state = &_ws_fail; 00245 stream->pass = size; 00246 if ( size < 126 ) 00247 { 00248 stream->data[1] &= 0x7f; 00249 stream->data[1] |= size; 00250 } 00251 else if ( size < 65537 ) 00252 { 00253 stream->data[1] &= 0x7f; 00254 stream->data[1] |= 126; 00255 stream->data[2] = ((size >> 8) & 0xff); 00256 stream->data[3] = ((size >> 0) & 0xff); 00257 } 00258 else 00259 { 00260 stream->data[1] &= 0x7f; 00261 stream->data[1] |= 127; 00262 stream->data[2] = ((size >> 56) & 0xff); 00263 stream->data[3] = ((size >> 48) & 0xff); 00264 stream->data[4] = ((size >> 40) & 0xff); 00265 stream->data[5] = ((size >> 32) & 0xff); 00266 stream->data[6] = ((size >> 24) & 0xff); 00267 stream->data[7] = ((size >> 16) & 0xff); 00268 stream->data[8] = ((size >> 8) & 0xff); 00269 stream->data[9] = ((size >> 0) & 0xff); 00270 } 00271 } 00272 00273 void ws_owire_end_frame ( struct ws_owire * stream ) 00274 { 00275 memset(stream->data, 0, 14); 00276 stream->state = &_ws_fail; 00277 stream->pass = 0; 00278 } 00279 00280 void ws_owire_last ( struct ws_owire * stream ) 00281 { 00282 // set bit 8. 00283 stream->data[0] |= 0x80; 00284 } 00285 00286 void ws_owire_eval ( struct ws_owire * stream, uint8 eval ) 00287 { 00288 // clear, then set bits 5-7. 00289 stream->data[0] &= 0xf1; 00290 stream->data[0] |= ((eval & 0x07) << 4); 00291 } 00292 00293 void ws_owire_code ( struct ws_owire * stream, uint8 code ) 00294 { 00295 // clear, then set bits 5-7. 00296 stream->data[0] &= 0xf0; 00297 stream->data[0] |= (code & 0x0f); 00298 } 00299 00300 void ws_owire_mask ( struct ws_owire * stream ) 00301 { 00302 // set bit 8. 00303 stream->data[1] |= 0x80; 00304 } 00305 00306 uint64 ws_owire_feed 00307 ( struct ws_owire * stream, const void * data, uint64 size ) 00308 { 00309 return (stream->state(stream, static_cast<const uint8*>(data), size)); 00310 } 00311 00312 void ws_owire_put_text 00313 ( struct ws_owire * stream, const void * data, uint64 size ) 00314 { 00315 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x01); 00316 } 00317 00318 void ws_owire_put_data 00319 ( struct ws_owire * stream, const void * data, uint64 size ) 00320 { 00321 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x02); 00322 } 00323 00324 void ws_owire_put_kill 00325 ( struct ws_owire * stream, const void * data, uint64 size ) 00326 { 00327 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x08); 00328 } 00329 00330 void ws_owire_put_ping 00331 ( struct ws_owire * stream, const void * data, uint64 size ) 00332 { 00333 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x09); 00334 } 00335 00336 void ws_owire_put_pong 00337 ( struct ws_owire * stream, const void * data, uint64 size ) 00338 { 00339 ws_owire_put_full(stream, static_cast<const uint8*>(data), size, 0x0a); 00340 } 00341