cwebs 0.2
WebSocket wire protocol.
code/owire.c
Go to the documentation of this file.
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 
 All Classes Files Functions