OSSP CVS Repository

ossp - Check-in [2729]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2729
Date: 2002-Nov-05 14:23:36 (local)
2002-Nov-05 13:23:36 (UTC)
User:mlelstv
Branch:
Comment: snapshot - sio_strategy now has a default direction triggered by SIO_OK result - added structure tag to aid debugging - sio_hole eats all data and returns downstream (correct ?) - sio_null now uses default directio - sio_sa puts wrapper on sa objects - sio_hello.c implements a trivial protocol handler

PR: Submitted by: Reviewed by: Approved by: Obtained from:

Tickets:
Inspections:
Files:
ossp-pkg/sio/sio.c      1.3 -> 1.4     29 inserted, 3 deleted
ossp-pkg/sio/sio_hello.c      added-> 1.1
ossp-pkg/sio/sio_hole.c      1.1 -> 1.2     3 inserted, 7 deleted
ossp-pkg/sio/sio_null.c      1.2 -> 1.3     2 inserted, 2 deleted
ossp-pkg/sio/sio_sa.c      added-> 1.1
ossp-pkg/sio/sio_test.c      1.1 -> 1.2     56 inserted, 15 deleted

ossp-pkg/sio/sio.c 1.3 -> 1.4

--- sio.c        2002/10/24 07:46:01     1.3
+++ sio.c        2002/11/05 13:23:36     1.4
@@ -58,6 +58,8 @@
     NODE(sio_halfduplex_t) hd;
     sio_stage_t *stage;
     sio_halfduplex_t *cross;
+    const char *tag;
+    sio_rc_t rc_with_data, rc_no_data;
     al_t *al;
     sio_rc_t (*func)(sio_t *, al_t *, void *);
 };
@@ -99,15 +101,28 @@
      * call stage and direct data upstream/downstream
      * according to response code
      *
+     * if stage directs SIO_OK, chose default direction
+     * depending on data in assembly line
+     *
      * if we the stage does not return a direction,
      * simply end the code
      *
      * if we drop off the chain, simply result SIO_OK
      *
      */
-    h = chain;
+    rc = SIO_UPSTREAM;
+    h  = chain;
     while (h != NULL) {
         rc = h->func(sio, h->al, h->stage->userdata);
+
+        /* chose default direction */
+        if (rc == SIO_OK) {
+            if (al_bytes(h->al) > 0)
+                rc = h->rc_with_data;
+            else
+                rc = h->rc_no_data;
+        }
+
         if (rc == SIO_UPSTREAM)
             h = NEXT(h,hd);
         else if (rc == SIO_DOWNSTREAM)
@@ -176,17 +191,28 @@
 
     NODEINIT(&sios->reader,hd);
     NODEINIT(&sios->writer,hd);
+
     sios->module       = siom;
+
     sios->userdata     = NULL;
     sios->rw           = SIO_MODE_INVALID;
-    sios->reader.func  = siom->input;
+    sios->reader.func  = sios->module->input;
     sios->reader.stage = sios;
-    sios->writer.func  = siom->output;
+    sios->writer.func  = sios->module->output;
     sios->writer.stage = sios;
 
     sios->reader.cross = &sios->writer;
     sios->writer.cross = &sios->reader;
 
+    sios->reader.tag   = "reader";
+    sios->writer.tag   = "writer";
+
+    /* default rules */
+    sios->reader.rc_with_data = SIO_DOWNSTREAM;
+    sios->reader.rc_no_data   = SIO_UPSTREAM;
+    sios->writer.rc_with_data = SIO_UPSTREAM;
+    sios->writer.rc_no_data   = SIO_DOWNSTREAM;
+
     rc = sios->module->init(sio, &sios->userdata);
     if (rc != SIO_OK) {
         free(sios);


ossp-pkg/sio/sio_hello.c -> 1.1

*** /dev/null    Sat Nov 23 01:03:56 2024
--- -    Sat Nov 23 01:03:56 2024
***************
*** 0 ****
--- 1,302 ----
+ 
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
+ 
+ #include "al.h"
+ #include "sio.h"
+ #include "sio_module.h"
+ 
+ #define PROMPT "Login: "
+ #define NPROMPT (sizeof(PROMPT)-1)
+ 
+ #define PASSWD "Geheim\r\n"
+ #define NPASS (sizeof(PASSWD)-1)
+ 
+ /*
+  * protocol states
+  */
+ typedef enum {
+     INIT,      /* setting up protocol, save output or switch to writer */
+     PROMPTING, /* sending prompt string as writer */
+     PROMPTED,  /* continue sending, switch to reader when done */
+     WAIT,      /* gather password as reader, flush buffer if good */
+     GOOD,      /* default null operation */
+     BAD        /* drop output, return eof on input */
+ } state_t;
+ 
+ typedef struct {
+     al_t *al_in, *al_out;  /* cache input and output stream */
+     state_t state;
+     char passwd[NPASS];    /* input buffer */
+     int  npass;            /* characters in input buffer */
+     al_t *pre;             /* saved output during protocol */
+     int isoutput;          /* remember originator of protocol */
+     void *data_label;      /* al labels used by SIO */
+     void *eof_label;
+     char eof;              /* eof label buffer */
+ } private_t;
+ 
+ /***********************************************************************/
+ 
+ /*
+  * create stage
+  *
+  * allocate private instance data
+  */
+ static
+ sio_rc_t hello_init(sio_t *sio, void **u)
+ {
+     private_t *my;
+     
+     my = (private_t *)malloc(sizeof(private_t));
+     if (my == NULL)
+         return SIO_ERR_MEM;
+ 
+     sio_label(sio, SIO_LN_DATA, &my->data_label);
+     sio_label(sio, SIO_LN_EOF, &my->eof_label);
+ 
+     my->eof   = '\0';
+ 
+     *u = my;
+ 
+     return SIO_OK;
+ }
+ 
+ /*
+  * configure stage
+  *
+  * pass two void pointers
+  */
+ static
+ sio_rc_t hello_configure(sio_t *sio, void *u, void *obj, void *val)
+ {
+     return SIO_ERR_ARG;
+ }
+ 
+ /*
+  * destroy stage
+  */
+ static
+ sio_rc_t hello_cleanup(sio_t *sio, void *u)
+ {
+     private_t *my = (private_t *)u;
+ 
+     al_destroy(my->pre);
+ 
+     free(my);
+ 
+     return SIO_OK;
+ }
+ 
+ static
+ void hello_setup(sio_t *sio, private_t *my)
+ {
+     my->state  = INIT;
+     my->npass  = 0;
+ }
+ 
+ static
+ sio_rc_t hello_openr(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+ 
+     hello_setup(sio,my);
+     my->al_in = al;
+ 
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t hello_closer(sio_t *sio, al_t *al, void *u)
+ {
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t hello_openw(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+ 
+     hello_setup(sio,my);
+     al_create(&my->pre);
+     my->al_out = al;
+ 
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t hello_closew(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+ 
+     al_destroy(my->pre);
+     my->pre = NULL;
+ 
+     return SIO_OK;
+ }
+ 
+ /************************************************************************/
+ 
+ static
+ void hello_clearinput(private_t *my)
+ {
+     al_splice(my->al_in, 0, al_bytes(my->al_in), NULL, NULL);
+ }
+ 
+ static
+ void hello_clearoutput(private_t *my)
+ {
+     al_splice(my->al_out, 0, al_bytes(my->al_out), NULL, NULL);
+ }
+ 
+ /*
+  * gather input in password buffer
+  * return true if enough bytes or if no more data follows
+  */
+ static
+ int hello_readpasswd(private_t *my)
+ {
+     size_t actual;
+ 
+     al_flatten(my->al_in, 0, NPASS - my->npass, AL_FORWARD_SPAN, my->data_label,
+                my->passwd, &actual);
+     al_splice(my->al_in, 0, actual, NULL, NULL);
+     my->npass += actual;
+ 
+     /* flush input when buffer full or labels are switching */
+     return my->npass == NPASS || al_bytes(my->al_in) > 0;
+ }
+ 
+ /*
+  * write eof token to input stream
+  */
+ static
+ void hello_writeeof(private_t *my)
+ {
+     hello_clearinput(my);
+     al_append_bytes(my->al_in, &my->eof, sizeof(my->eof), my->eof_label);
+ }
+ 
+ /*
+  * defer initial output until protocol is done
+  */
+ static
+ void hello_saveoutput(private_t *my)
+ {
+     al_splice(my->pre, al_bytes(my->pre), 0, my->al_out, NULL);
+ }
+ 
+ /*
+  * restore saved output after handshake completed successfully
+  */
+ static
+ void hello_restoreoutput(private_t *my)
+ {
+     al_splice(my->al_out, 0, 0, my->pre, NULL);
+ }
+ 
+ /*
+  * write prompt string to output
+  */
+ static
+ void hello_sendprompt(private_t *my)
+ {
+         al_prepend_bytes(my->al_out, PROMPT, NPROMPT, my->data_label);
+ }
+ 
+ /************************************************************************/
+ 
+ #define GOTO(s, c) do { my->state = (s); rc = (c); } while(0)
+ 
+ static
+ sio_rc_t hello_protocol(sio_t *sio, private_t *my, int isoutput)
+ {
+     sio_rc_t rc = SIO_ERR_INT;
+     int good;
+ 
+     switch (my->state) {
+     case INIT:
+         if (isoutput) {
+             my->isoutput = 1;
+             hello_saveoutput(my);
+             GOTO(PROMPTING, SIO_UPSTREAM);
+         } else {
+             my->isoutput = 0;
+             GOTO(PROMPTING, SIO_XSTREAM);
+         }
+         break;
+     case PROMPTING:
+         assert(isoutput == 1);
+         hello_sendprompt(my);
+         GOTO(PROMPTED, SIO_UPSTREAM);
+         break;
+     case PROMPTED:
+         assert(isoutput == 1);
+         GOTO(WAIT, SIO_XSTREAM);
+         break;
+     case WAIT:
+         assert(isoutput == 0);
+         if (!hello_readpasswd(my))
+             GOTO(WAIT, SIO_UPSTREAM);
+         else {
+             good = my->npass == NPASS &&
+                    memcmp(my->passwd, PASSWD, NPASS) == 0;
+             if (!good) {
+                 if (my->isoutput)
+                     GOTO(BAD, SIO_XSTREAM);
+                 else {
+                     hello_writeeof(my);
+                     GOTO(BAD, SIO_DOWNSTREAM);
+                 }
+             } else if (my->isoutput) {
+                 hello_restoreoutput(my);
+                 GOTO(GOOD, SIO_XSTREAM);
+             } else
+                 GOTO(GOOD, SIO_OK);
+         }
+ 
+         break;
+     case GOOD:
+         GOTO(GOOD, SIO_OK);             /* default action */
+         break;
+     case BAD:
+         if (isoutput)
+             hello_clearoutput(my);
+         else
+             hello_writeeof(my);
+ 
+         GOTO(BAD, SIO_DOWNSTREAM);
+         break;
+     }
+ 
+     return rc;
+ }
+ 
+ /************************************************************************/
+ 
+ static
+ sio_rc_t hello_input(sio_t *sio, al_t *al, void *u)
+ {
+     return hello_protocol(sio, (private_t *)u, 0);
+ }
+ 
+ static
+ sio_rc_t hello_output(sio_t *sio, al_t *al, void *u)
+ {
+     return hello_protocol(sio, (private_t *)u, 1);
+ }
+ 
+ sio_module_t sio_module_hello = {
+     "hello",
+     hello_init,
+     hello_configure,
+     hello_cleanup,
+     hello_openr,
+     hello_closer,
+     hello_openw,
+     hello_closew,
+     hello_input,
+     hello_output
+ };
+ 


ossp-pkg/sio/sio_hole.c 1.1 -> 1.2

--- sio_hole.c   2002/10/23 17:05:10     1.1
+++ sio_hole.c   2002/11/05 13:23:36     1.2
@@ -6,6 +6,7 @@
 #include "sio_module.h"
 
 typedef struct {
+    int dummy;
 } private_t;
 
 /*
@@ -78,15 +79,10 @@
 static
 sio_rc_t hole_input(sio_t *sio, al_t *al, void *u)
 {
-    size_t feed = al_bytes(al);
-
     /* drop all data into the bit bucket */
-    if (feed > 0) {
-        al_splice(al, 0, feed, NULL, NULL);
-        return SIO_DOWNSTREAM;
-    }
+    al_splice(al, 0, al_bytes(al), NULL, NULL);
 
-    return SIO_UPSTREAM;
+    return SIO_DOWNSTREAM;
 }
 
 static


ossp-pkg/sio/sio_null.c 1.2 -> 1.3

--- sio_null.c   2002/10/23 17:05:10     1.2
+++ sio_null.c   2002/11/05 13:23:36     1.3
@@ -89,13 +89,13 @@
 static
 sio_rc_t null_input(sio_t *sio, al_t *al, void *u)
 {
-    return SIO_DOWNSTREAM;
+    return SIO_OK;
 }
 
 static
 sio_rc_t null_output(sio_t *sio, al_t *al, void *u)
 {
-    return SIO_UPSTREAM;
+    return SIO_OK;
 }
 
 sio_module_t sio_module_null = {


ossp-pkg/sio/sio_sa.c -> 1.1

*** /dev/null    Sat Nov 23 01:03:56 2024
--- -    Sat Nov 23 01:03:56 2024
***************
*** 0 ****
--- 1,224 ----
+ #include <stddef.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/uio.h>
+ #include <unistd.h>
+ 
+ #include "al.h"
+ #include "sio.h"
+ #include "sio_module.h"
+ 
+ #include "sa.h"
+ 
+ typedef struct {
+     char *mem;
+     size_t size;
+ } buffer_t;
+ 
+ typedef struct {
+     sa_t *sa;
+     buffer_t input;
+     size_t written;
+     void *label_data;
+     void *label_error;
+     void *label_eof;
+     char eof;
+     char error;
+ } private_t;
+ 
+ /*
+  * create stage
+  *
+  * allocate private instance data
+  */
+ static
+ sio_rc_t sa_init(sio_t *sio, void **u)
+ {
+     private_t *my;
+     
+     my = (private_t *)malloc(sizeof(private_t));
+     if (my == NULL)
+         return SIO_ERR_MEM;
+ 
+     my->sa           = NULL;
+ 
+     my->input.mem    = NULL;
+     my->input.size   = 0;
+ 
+     sio_label(sio, SIO_LN_DATA,  &my->label_data);
+     sio_label(sio, SIO_LN_ERROR, &my->label_error);
+     sio_label(sio, SIO_LN_EOF,   &my->label_eof);
+ 
+     my->eof   = '\0';
+     my->error = '\0';
+ 
+     *u = my;
+ 
+     return SIO_OK;
+ }
+ 
+ /*
+  * configure stage
+  *
+  */
+ static
+ sio_rc_t sa_configure(sio_t *sio, void *u, void *obj, void *val)
+ {
+     private_t *my = (private_t *)u;
+     const char *name = (const char *)obj;
+ 
+     if (!strcmp(name, "sa")) {
+         my->sa = (sa_t *)val;
+     } else if (!strcmp(name, "buflen")) {
+         my->input.size = *(size_t *)val;
+     } else {
+         return SIO_ERR_ARG;
+     }
+ 
+     return SIO_OK;
+ }
+ 
+ /*
+  * destroy stage
+  */
+ static
+ sio_rc_t sa_cleanup(sio_t *sio, void *u)
+ {
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t sa_openr(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+     buffer_t *buf = &my->input;
+     char *p;
+     size_t n;
+ 
+     n = buf->size;
+     p = realloc(buf->mem, n);
+     if (p != NULL)
+         buf->mem = p;
+ 
+     if (buf->mem == NULL)
+         return SIO_ERR_MEM;
+ 
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t sa_closer(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+     buffer_t *buf = &my->input;
+ 
+     if (buf->mem != NULL) {
+         free(buf->mem);
+         buf->mem = NULL;
+     }
+ 
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t sa_openw(sio_t *sio, al_t *al, void *u)
+ {
+     return SIO_OK;
+ }
+ 
+ static
+ sio_rc_t sa_closew(sio_t *sio, al_t *al, void *u)
+ {
+     return SIO_OK;
+ }
+ 
+ static
+ void sa_writeeof(al_t *al, private_t *my)
+ {
+     al_splice(al, 0, al_bytes(al), NULL, NULL);
+     al_append_bytes(al, &my->eof, sizeof(my->eof), my->label_eof);
+ }
+ 
+ static
+ void sa_writeerror(al_t *al, private_t *my)
+ {
+     al_splice(al, 0, al_bytes(al), NULL, NULL);
+     al_append_bytes(al, &my->error, sizeof(my->error), my->label_error);
+ }
+ 
+ static
+ sio_rc_t sa_input(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+     buffer_t *buf = &my->input;
+     size_t actual;
+     sa_rc_t src;
+ 
+     src = sa_read(my->sa, buf->mem, buf->size, &actual);
+     if (src != SA_OK) {
+         sa_writeerror(al, my);
+         return SIO_DOWNSTREAM;
+     } else if (src == SA_ERR_EOF) {
+         sa_writeeof(al, my);
+         return SIO_DOWNSTREAM;
+     }
+ 
+     al_append_bytes(al, buf->mem, actual, my->label_data);
+ 
+     return SIO_DOWNSTREAM;
+ }
+ 
+ static
+ al_rc_t sa_output_chunk(al_chunk_t *alc, void *u)
+ {
+     private_t *my = (private_t *)u;
+     char   *p;
+     size_t n, actual;
+     sa_rc_t src;
+ 
+     p = al_chunk_ptr(alc, 0);
+     n = al_chunk_len(alc);
+ 
+     src = sa_write(my->sa, p, n, &actual);
+     if (src != SA_OK)
+         return AL_ERR_EOF;
+ 
+     my->written += actual; /* XXX not used */
+ 
+     return AL_OK;
+ }
+ 
+ static
+ sio_rc_t sa_output(sio_t *sio, al_t *al, void *u)
+ {
+     private_t *my = (private_t *)u;
+     al_rc_t arc;
+     size_t n = al_bytes(al);
+ 
+     my->written = 0;
+ 
+     arc = al_traverse_cb(al, 0, n, AL_FORWARD, my->label_data,
+                          sa_output_chunk, u);
+     if (arc != AL_OK) return SIO_ERR_INT;
+ 
+     arc = al_splice(al, 0, al_bytes(al), NULL, NULL);
+     if (arc != AL_OK) return SIO_ERR_INT;
+ 
+     return SIO_DOWNSTREAM;
+ }
+ 
+ sio_module_t sio_module_sa = {
+     "sa",
+     sa_init,
+     sa_configure,
+     sa_cleanup,
+     sa_openr,
+     sa_closer,
+     sa_openw,
+     sa_closew,
+     sa_input,
+     sa_output
+ };
+ 
+ 


ossp-pkg/sio/sio_test.c 1.1 -> 1.2

--- sio_test.c   2002/10/23 17:05:10     1.1
+++ sio_test.c   2002/11/05 13:23:36     1.2
@@ -3,44 +3,85 @@
 #include "al.h"
 #include "sio.h"
 
-extern sio_module_t sio_module_fd;
+#include "sa.h"
+
+extern sio_module_t sio_module_sa;
+extern sio_module_t sio_module_hello;
 extern sio_module_t sio_module_buffer;
 
 #define e(f) rc = f; printf("%s = %s\n",#f, sio_error(rc)); fflush(stdout);
+#define s(f) src = f; printf("%s = %s\n",#f, sa_error(src)); fflush(stdout);
 
 int main(int argc, char *argv[])
 {
     sio_rc_t rc;
     sio_t *sio;
-    sio_stage_t *sios_fd, *sios_buffer;
-    int fd;
+    sio_stage_t *sios_sa, *sios_hello, *sios_buffer;
+
+    sa_rc_t src;
+    sa_addr_t *saa;
+    sa_t *msa, *sa;
+    char *uri;
+
     char buf[] = "Hello world\n";
+
     size_t actual;
-    size_t buflen = 1000;
+    size_t buflen;
 
-    fd = fileno(stdout);
+    s(sa_create(&msa));
+    s(sa_option(msa, SA_OPTION_REUSEADDR, 1));
 
-    e(sio_create(&sio));
+    s(sa_addr_create(&saa));
+    uri = "inet://localhost:25001#tcp";
+    s(sa_addr_u2a(saa, uri));
+    s(sa_bind(msa,saa));
+    s(sa_addr_destroy(saa));
+    uri = NULL;
 
+    e(sio_create(&sio));
+    e(sio_create_stage(sio, &sio_module_sa, &sios_sa));
+    e(sio_create_stage(sio, &sio_module_hello, &sios_hello));
     e(sio_create_stage(sio, &sio_module_buffer, &sios_buffer));
+
+    buflen = 256;
+    e(sio_configure_stage(sio, sios_sa, "buflen", &buflen));
+
+    buflen = 1000;
     e(sio_configure_stage(sio, sios_buffer, "outputsize", &buflen));
-    e(sio_create_stage(sio, &sio_module_fd, &sios_fd));
-    e(sio_configure_stage(sio, sios_fd, "fd", &fd));
 
-    e(sio_attach(sio, sios_buffer, SIO_MODE_WRITE));
-    e(sio_attach(sio, sios_fd, SIO_MODE_WRITE));
+    s(sa_listen(msa, 5));
+
+    for(;;) {
+
+        s(sa_accept(msa, &saa, &sa));
+        s(sa_addr_a2u(saa, &uri));
+        printf("Connection from %s\n",uri);
+        s(sa_addr_destroy(saa));
+
+        e(sio_configure_stage(sio, sios_sa, "sa", sa));
 
-    e(sio_write(sio, buf, sizeof(buf)-1, &actual));
+        e(sio_attach(sio, sios_buffer, SIO_MODE_WRITE));
+        e(sio_attach(sio, sios_hello, SIO_MODE_READWRITE));
+        e(sio_attach(sio, sios_sa, SIO_MODE_READWRITE));
 
-    e(sio_push(sio));
+        e(sio_write(sio, buf, sizeof(buf)-1, &actual));
+        e(sio_push(sio));
+
+        e(sio_detach(sio, sios_sa));
+        e(sio_detach(sio, sios_hello));
+        e(sio_detach(sio, sios_buffer));
+
+        sa_destroy(sa);
+    }
 
-    e(sio_detach(sio, sios_fd));
-    e(sio_detach(sio, sios_buffer));
 
-    e(sio_destroy_stage(sio, sios_fd));
     e(sio_destroy_stage(sio, sios_buffer));
+    e(sio_destroy_stage(sio, sios_hello));
+    e(sio_destroy_stage(sio, sios_sa));
 
     e(sio_destroy(sio));
 
+    sa_destroy(msa);
+
     return 0;
 }

CVSTrac 2.0.1