💾 Archived View for gmi.noulin.net › gitRepositories › tuyau › file › netFrame.c.gmi captured on 2023-01-29 at 13:27:20. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

tuyau

Log

Files

Refs

README

netFrame.c (6835B)

     1 
     2 
     3 /* Libsheepy documentation: https://spartatek.se/libsheepy/ */
     4 
     5 #include "netFrame.h"
     6 #include "netFrameInternal.h"
     7 
     8 #include <sys/types.h>
     9 #include <sys/socket.h>
    10 #include <errno.h>
    11 
    12 void initiateNetFrame(netFramet *self);
    13 void registerMethodsNetFrame(netFrameFunctionst *f);
    14 void initiateAllocateNetFrame(netFramet **self);
    15 void finalizeNetFrame(void);
    16 netFramet* allocNetFrame(void);
    17 local void freeNetFrame(netFramet *self);
    18 local void terminateNetFrame(netFramet **self);
    19 local char* toStringNetFrame(netFramet *self);
    20 local netFramet* duplicateNetFrame(netFramet *self);
    21 local void smashNetFrame(netFramet **self);
    22 local void finishNetFrame(netFramet **self);
    23 local const char* helpNetFrame(netFramet *self);
    24 local void setCallbackNetFrame(netFramet *self, callBackNetFramet callback, void* context);
    25 local bool sendNetFrame(netFramet *self, SSL *ssl, void* buf, size_t size);
    26 local bool receiveNetFrame(netFramet *self, SSL *ssl);
    27 local bool receiveOneNetFrame(netFramet *self, SSL *ssl);
    28 local bool endNetFrame(netFramet *self, SSL *ssl);
    29 
    30 /* enable/disable logging */
    31 /* #undef pLog */
    32 /* #define pLog(...) */
    33 
    34 bool checkLibsheepyVersionNetFrame(const char *currentLibsheepyVersion) {
    35   return eqG(currentLibsheepyVersion, LIBSHEEPY_VERSION);
    36 }
    37 
    38 void initiateNetFrame(netFramet *self) {
    39 
    40   self->type = "netFrame";
    41   if (!netFrameF) {
    42     netFrameF            = malloc(sizeof(netFrameFunctionst));
    43     registerMethodsNetFrame(netFrameF);
    44     pErrorNot0(atexit(finalizeNetFrame));
    45   }
    46   self->f = netFrameF;
    47 
    48   self->callback = null;
    49   self->context  = null;
    50 }
    51 
    52 void registerMethodsNetFrame(netFrameFunctionst *f) {
    53 
    54   f->free        = freeNetFrame;
    55   f->terminate   = terminateNetFrame;
    56   f->toString    = toStringNetFrame;
    57   f->duplicate   = duplicateNetFrame;
    58   f->smash       = smashNetFrame;
    59   f->finish      = finishNetFrame;
    60   f->help        = helpNetFrame;
    61   f->setCallback = setCallbackNetFrame;
    62   f->send        = sendNetFrame;
    63   f->receive     = receiveNetFrame;
    64   f->receiveOne  = receiveOneNetFrame;
    65   f->end         = endNetFrame;
    66 }
    67 
    68 void initiateAllocateNetFrame(netFramet **self) {
    69 
    70   if (self) {
    71     (*self) = malloc(sizeof(netFramet));
    72     if (*self) {
    73       initiateNetFrame(*self);
    74     }
    75   }
    76 }
    77 
    78 void finalizeNetFrame(void) {
    79 
    80   if (netFrameF) {
    81     freen(netFrameF);
    82   }
    83 }
    84 
    85 netFramet* allocNetFrame(void) {
    86   netFramet *r = NULL;
    87 
    88   initiateAllocateNetFrame(&r);
    89   ret r;
    90 }
    91 
    92 
    93 void cleanUpNetFrameTerminateG(netFramet **val) {
    94   terminateO(*val);
    95 }
    96 
    97 void cleanUpNetFrameFreeG(netFramet *val) {
    98   freeO(val);
    99 }
   100 
   101 void cleanUpNetFrameFinishG(netFramet *val) {
   102   finishO(val);
   103 }
   104 
   105 local void freeNetFrame(netFramet *self UNUSED) {
   106 }
   107 
   108 local void terminateNetFrame(netFramet **self) {
   109 
   110   freeNetFrame(*self);
   111   finishNetFrame(self);
   112 }
   113 
   114 
   115 local char* toStringNetFrame(netFramet *self UNUSED) {
   116 
   117   ret strdup("TODO - netFrame");
   118 }
   119 
   120 local netFramet* duplicateNetFrame(netFramet *self UNUSED) {
   121 
   122   createAllocateNetFrame(dup);
   123   ret dup;
   124 }
   125 
   126 local void smashNetFrame(netFramet **self) {
   127 
   128   finishNetFrame(self);
   129 }
   130 
   131 #if NFreeStackCheck
   132 local void finishNetFrame(netFramet **self) {
   133 
   134   register u64 rsp asm("rsp");
   135   if ((u64)*self > rsp) {
   136     logW("Probably trying to free a smallArray on stack: "BLD"%p"RST" sp: "BLD"%p"RST, *self, rsp);
   137     logBtrace;
   138   }
   139   else {
   140     freen(*self);
   141   }
   142 }
   143 #else
   144 // #if NFreeStackCheck
   145 local void finishNetFrame(netFramet **self) {
   146 
   147   freen(*self);
   148 }
   149 #endif
   150 // #if NFreeStackCheck
   151 
   152 local const char* helpNetFrame(netFramet UNUSED *self) {
   153   ret "TODO - netFrame help";
   154 }
   155 
   156 
   157 local void setCallbackNetFrame(netFramet *self, callBackNetFramet callback, void* context) {
   158   self->callback = callback;
   159   self->context  = context;
   160 }
   161 
   162 
   163 local bool sendNetFrame(netFramet *self UNUSED, SSL *ssl, void* buf, size_t size) {
   164 
   165   ssize_t status; // for netsend
   166 
   167   #define netsend(B,SZ,FLGS) procbegin\
   168     UNIQVAR(retry):\
   169     if ((status = SSL_write(ssl, B, SZ)) < 0) {\
   170       /* TODO SSL_get_error() */\
   171       shperror("Netframe send ssl error");\
   172       ret no;\
   173     }\
   174     procend
   175 
   176   if (size > 0) {
   177     netsend(&size, sizeof(size), MSG_MORE);
   178   }
   179   else {
   180     // size 0 is the last frame in this transaction
   181     netsend(&size, sizeof(size), 0);
   182     ret yes;
   183   }
   184 
   185   while(size > 0) {
   186     netsend(buf, size, 0);
   187     buf  += status;
   188     size -= status;
   189   }
   190 
   191   ret yes;
   192 }
   193 
   194 
   195 local bool receiveNetFrame(netFramet *self, SSL *ssl) {
   196   if (!self->callback) ret no;
   197 
   198   size_t size;
   199   ssize_t status; // for netrecv
   200   bool isFirstFrame = yes;
   201 
   202   #define netrecv(B, SZ, FLGS, CHECK, ENOUGH, ERROR) procbegin\
   203    UNIQVAR(retry):\
   204    if ((status = SSL_read(ssl, B, SZ)) < 0) {\
   205       /* TODO SSL_get_error() */\
   206      shperror("Netframe recv socket error");\
   207      ERROR;\
   208      ret no;\
   209    }\
   210    elif (!status) {\
   211      /* ending connection - stop receiving frames */\
   212      CHECK;\
   213    }\
   214   procend
   215 
   216   forever {
   217     netrecv(&size, sizeof(size), MSG_WAITALL, logE("ending connection");ret no,,logE("recv frame size"));
   218 
   219     if (size == 0) {
   220       /* the last frame for this transaction is received, leave this loop */
   221       if (isFirstFrame) {
   222         /* the first frame has size 0, this is a request to close the connection */
   223         logD("close socket");
   224         int sock = SSL_get_fd(ssl);
   225         close(sock);
   226       }
   227       break;
   228     }
   229 
   230     //logVarG(size);
   231 
   232     cleanCharP(buf) = malloc(size);
   233     if (!buf) ret no;
   234 
   235     void   *b  = buf;
   236     size_t  sz = size;
   237     while (sz > 0) {
   238       netrecv(b, sz, MSG_WAITALL /*flags*/, logE("ending connection: received %i, expected %i, left to receive %i", size-sz, size, sz);ret no/*frame is incomplete*/,, logE("Received: %i, left to receive: %i", size-sz ,sz));
   239       b  += status;
   240       sz -= status;
   241     }
   242 
   243     if (!self->callback(buf, size, self->context)) {
   244       // TODO error
   245     }
   246     isFirstFrame = no;
   247   }
   248 
   249   ret yes;
   250 }
   251 
   252 local bool receiveOneNetFrame(netFramet *self, SSL *ssl) {
   253   if (!self->callback) ret no;
   254 
   255   size_t size;
   256   ssize_t status; // for netrecv
   257 
   258   netrecv(&size, sizeof(size), MSG_WAITALL, logI("ending connection");ret no/*frame is incomplete*/,,logE("recv size"));
   259 
   260   //logVarG(size);
   261 
   262   if (!size) {
   263     // a frame size 0 is a request to close the connection
   264     logD("close socket");
   265     int sock = SSL_get_fd(ssl);
   266     close(sock);
   267     ret yes;
   268   }
   269 
   270   cleanCharP(buf) = malloc(size);
   271   if (!buf) ret no;
   272 
   273   void   *b  = buf;
   274   size_t  sz = size;
   275   while (sz > 0) {
   276     netrecv(b, sz, MSG_WAITALL /*flags*/, logI("ending connection");ret no/*frame is incomplete*/, logD("Received: %i, left to receive: %i", size-sz ,sz), logE("Received: %i, left to receive: %i", size-sz ,sz));
   277     b  += status;
   278     sz -= status;
   279   }
   280 
   281   if (!self->callback(buf, size, self->context)) {
   282     // TODO error
   283   }
   284   ret yes;
   285 }
   286 
   287 local bool endNetFrame(netFramet *self, SSL *ssl) {
   288   ret sendNetFrame(self, ssl, null, 0);
   289 }
   290 
   291 
   292 // vim: set expandtab ts=2 sw=2: