]> SAFE projects GIT repository - jmp/mailleur/commitdiff
server implementation demo within kleenex
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Tue, 30 Jul 2024 14:26:39 +0000 (10:26 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Tue, 30 Jul 2024 14:26:39 +0000 (10:26 -0400)
Makefile
app/emlrec.c
kleenex/Makefile [new file with mode: 0644]
kleenex/server.c [new file with mode: 0644]
lib/gestcp.c
lib/modrec.c
lib/subrou.c
lib/unisoc.c

index 3919fb509a25c7e7890e4265fb9dce9e3eea8028..b191f2269d1faeefc1cc4245fc5665808f091626 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,7 @@ install       :
 
 #--------------------------------------------------------------------
 SUBDIR =                                                               \
+          kleenex                                                      \
           lib                                                          \
           app                                                          \
 
index 8e82be9a6a0840508cf55bcc37e32333af0f559a..2b3ac758b73ea672b57678184c0b97599269b948 100644 (file)
@@ -18,7 +18,7 @@
 #define RECNAME "emlrec"
 
 //port listening format is "IP:PORT NUMBER:num iteration"
-#define PORTREC "192.168.0.1:25:2"
+#define PORTREC "192.168.0.1:25:1"
 /*
 \f
 */
diff --git a/kleenex/Makefile b/kleenex/Makefile
new file mode 100644 (file)
index 0000000..af5fa2f
--- /dev/null
@@ -0,0 +1,7 @@
+
+server :  server.c
+
+clean  :  
+          @ rm -f server server.o
+
+CFLAGS = -Wall -D_GNU_SOURCE -g
diff --git a/kleenex/server.c b/kleenex/server.c
new file mode 100644 (file)
index 0000000..8dd6a91
--- /dev/null
@@ -0,0 +1,84 @@
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void receiveAndRespond(int handle)
+
+{
+#define        TRY 5
+printf("Start receiveAndRespond\n");
+
+for (int i=0;i<TRY;i++) {
+  (void) dprintf(handle,"Connected %d/%d\n",i,TRY);
+  (void) sleep(1);
+  }
+printf("receiveAndRespond completed\n");
+}
+
+int main(int argc, char *argv[]) {
+
+    // Socket setup bits    
+    int reuse;
+    int server_fd, client_fd;  
+    struct linger slg;
+    struct sockaddr_in server_addr;
+
+    // Create socket 
+    server_fd = socket(AF_INET, SOCK_STREAM, 0);
+    reuse=1; 
+    setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
+    setsockopt(server_fd,SOL_SOCKET,SO_REUSEPORT,&reuse,sizeof(reuse));
+    slg.l_onoff=1;
+    slg.l_linger=0;
+    setsockopt(server_fd,SOL_SOCKET,SO_LINGER,&slg,sizeof(slg));
+       
+
+    // Bind to port
+    server_addr.sin_family = AF_INET;
+    inet_pton(AF_INET,"127.0.0.1", &(server_addr.sin_addr));
+    server_addr.sin_port = htons(2525);
+    bind(server_fd, (struct sockaddr*) &server_addr, sizeof(server_addr));
+
+    // Listen for connections
+    listen(server_fd, SOMAXCONN);
+
+    while (1) {
+        // Accept new connection
+        client_fd = accept(server_fd, NULL, NULL); 
+
+        // Print client connection message
+        printf("New client connected: %d\n", client_fd);
+
+        // Fork a child process 
+        pid_t pid = fork(); 
+
+        if (pid == 0) {
+           // Child process handles client
+           close(server_fd);  
+
+           // Receive data then send response
+           receiveAndRespond(client_fd);
+       
+          if (shutdown(client_fd,SHUT_RDWR)<0) {
+            (void) printf("Unable to shutdown properly (error=<%s>(\n",
+                           strerror(errno));
+            }
+          if (close(client_fd)<0) {
+            (void) printf("Unable to close properly (error=<%s>(\n",
+                           strerror(errno));
+            }
+           exit(EXIT_SUCCESS);
+
+       } else {
+           // Parent closes client socket
+           close(client_fd);                 
+       }
+    }
+}
index 2d44d279c91cbe4b069337b7e9ee47433be310c6..174e8dab6eef5c96965ff1bb49e296ed62768d5f 100644 (file)
@@ -56,7 +56,6 @@ if (contact<0) {
 else {
   int flags;
 
-  (void) rou_alert(0,"JMPDBG binding->handle '%d'",binding->handle);
   if ((flags=fcntl(contact,F_GETFL,0))<0)
     (void) rou_core_dump("%s Unable to get socket descripteur (error='%s')",
                           OPEP,strerror(errno));
@@ -106,8 +105,10 @@ while (proceed==true) {
         }
       break;
     case 2      :       //listening on the handle
+      (void) rou_alert(0,"JMPDBG contact handle ptr='%p'",&(binding->handle));
+      (void) soc_getlinger(binding->handle,"waitlisten 1");
       (void) soc_setlinger(binding->handle);
-      (void) soc_getlinger(binding->handle,"waitlisten");
+      (void) soc_getlinger(binding->handle,"waitlisten 2");
       break;
     case 3      :       //listening on the handle
       fd_set reading;
@@ -270,7 +271,7 @@ while (proceed==true) {
         }
       break;
     case 1      :       //waiting from contact
-      (void) rou_alert(0,"JMPDBG shutdown contact channel='%d'",contact->channel);
+      (void) soc_getlinger(contact->channel,"before shutdown");
       if (shutdown(contact->channel,SHUT_RDWR)<0) {
         switch (errno) {
           case ENOTCONN :       //already disconnect by other side!
@@ -282,7 +283,7 @@ while (proceed==true) {
           }
         }
       (void) usleep(10000);
-      (void) close(contact->channel);
+      //(void) close(contact->channel);
       break;
     case 2      :       //freeing contact memory
       (void) free(contact);              
index 7e0420ef11acca18cb471efcb44f16db84c781d3..2f88e176884086bf0be8d12f6c2e45cf51198907 100644 (file)
@@ -102,40 +102,10 @@ while (proceed==true) {
   switch (phase) {
     case 0      :       //dispatched  process still alive
       (void) prc_nozombie();
-      for (int i=0;i<binding->iteration;i++) {
-        if (binding->childs[i]==(pid_t)0)
-          continue;
-        if (prc_checkprocess(binding->childs[i])==false) {
-          (void) rou_alert(3,"%s, Process '%05d' exited",OPEP,binding->childs[i]);
-          binding->childs[i]=(pid_t)0;
-          }
-        }
       break;
     case 1      :               //dispating need process
-      for (int i=0;i<binding->iteration;i++) {
-        if (binding->childs[i]!=(pid_t)0)
-          continue;
-        (void) soc_getlinger(binding->handle,"before fork");
-        switch(binding->childs[i]=fork()) {
-          case -1       :
-            (void) rou_alert(0,"%s, Unable to start process to "
-                                "handle <%s:%s> socket (config?)",
-                                OPEP,binding->ip,binding->port);
-            break;
-          case 0        :               //the dispatched process
-            (void) closelog();
-            (void) openlog("Contact",LOG_NDELAY|LOG_PID,LOG_DAEMON);
-            (void) docontact(binding);  //waiting, handling remote contact
-            (void) rou_alert(0,"Contact Exiting: %s-%s",appname,rou_getversion());
-            (void) sleep(1);            //avoiding avalanche
-            (void) closelog();
-            (void) exit(0);
-            break;
-          default       :
-            (void) usleep(10000);       //wait for next fork
-            break;
-          }
-        }
+      (void) docontact(binding);  //waiting, handling remote contact
+      (void) rou_alert(0,"Contact Exiting: %s-%s",appname,rou_getversion());
       break;
     default     :       //SAFE Guard
       proceed=false;
@@ -173,7 +143,8 @@ while (proceed==true) {
       break;
     case 1      :       //check need to dispatch a process
       while (*bindings!=(SOCTYP *)0) {
-        (void) soc_getlinger((*bindings)->handle,"before displatching");
+        (void) rou_alert(0,"JMPDBG handle ptr='%p'",&((*bindings)->handle));
+        (void) soc_getlinger((*bindings)->handle,"before dispatching");
         (void) dispatching(*bindings);
         bindings++;
         }
@@ -273,7 +244,7 @@ int phase;
 _Bool proceed;
 
 bindings=(SOCTYP **)0;
-bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.25","2525",2);
+bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.25","2525",1);
 //bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1);
 phase=0;
 proceed=true;
@@ -281,6 +252,7 @@ while (proceed==true) {
   switch (phase) {
     case 0      :       //looping forever email receiving processes
       (void) prc_settitle("Emlrec Daemon");
+      (void) rou_alert(0,"-------------JMPDBG---------------");
       break;
     case 1      :       //Opening ALL channels
       if (soc_mullisten(bindings)==false) 
@@ -288,7 +260,8 @@ while (proceed==true) {
       break;
     case 2      :       //Terminating all remaining process
       (void) activate(bindings);
-      (void) sleep(5);
+      if ((hangup==false)&&(reload==false))
+        (void) sleep(5);
       if ((hangup==false)&&(reload==false))
         phase--;        //normal cycle, lets proceed to actvate again
       break;
index fb93f4aa6587a5fc8152ce2fc340e056a70bc144..458ce00e1f32cb553690a773c8bf835fa9f0defc 100644 (file)
@@ -18,8 +18,8 @@
 
 
 //version definition 
-#define VERSION "0.2"
-#define RELEASE "3"
+#define VERSION "0.3"
+#define RELEASE "1"
 
 //Public variables
 PUBLIC  int debug=0;            //debug level
index 0b4d032f152c77a0d725e63808455788df675bba..abc8dcb9d02361c51f64249f689e6680185f4a1a 100644 (file)
@@ -67,7 +67,7 @@ static int bindhandle(struct addrinfo *ai,SOCTYP *binding)
 
 int handle;
 struct linger slg;
-char *buf;
+int reuse;
 int flags;
 int phase;
 _Bool proceed;
@@ -75,17 +75,11 @@ _Bool proceed;
 handle=-1;
 slg.l_onoff=true;
 slg.l_linger=0; /*0 sec timeout on close*/
-buf=calloc(BFSZ,sizeof(char));
+reuse=1;
 flags=0;
 phase=0;
 proceed=true;
 while (proceed==true) {
-  if (handle>=0) {
-    char bigre[50];
-
-    (void) sprintf(bigre,"Phase='%02d'",phase);
-    (void) soc_getlinger(handle,bigre);
-    }
   switch (phase) {
     case 0     :       //lets get a socket
       if ((handle=socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol))<0) {
@@ -94,23 +88,39 @@ while (proceed==true) {
        phase=999;      //trouble trouble
        }
       break;
-    case 1     :       //setting socket option (address)
-      if (setsockopt(handle,SOL_SOCKET,SO_REUSEADDR,buf,BFSZ*sizeof(char))<0) {
+    case 1     :       /*getting socket option */
+      if ((flags=fcntl(handle,F_GETFL,0))<0) {
+        (void) rou_alert(0,"%s Unable to set socket descriptor "
+                           "for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 2     :       //setting the socket working setting
+      if (fcntl(handle,F_SETFL,flags|O_NONBLOCK|O_ASYNC)<0) {
+        (void) rou_alert(0,"%s Unable to set socket in none "
+                           "block mode for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 3     :       //setting socket option (address)
+      if (setsockopt(handle,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0) {
         (void) rou_alert(0,"%s Unable to get socket option "
                            "SO_REUSEADDR for <%s> (error='%s')",
                           OPEP,ai->ai_canonname,strerror(errno));
         phase=999;     //trouble cleanup phase
         }
       break;
-    case 2     :       //setting socket option (port)
-      if (setsockopt(handle,SOL_SOCKET,SO_REUSEPORT,buf,BFSZ*sizeof(char))<0) {
+    case 4     :       //setting socket option (port)
+      if (setsockopt(handle,SOL_SOCKET,SO_REUSEPORT,&reuse,sizeof(reuse))<0) {
         (void) rou_alert(0,"%s Unable to get socket option "
                            "SO_REUSEPORT for <%s> (error='%s')",
                           OPEP,ai->ai_canonname,strerror(errno));
         phase=999;     //trouble cleanup phase
         }
       break;
-    case 3     :       //SO_LINGER allow  Connection reset by peer
+    case 5     :       //SO_LINGER allow  Connection reset by peer
       if (setsockopt(handle,SOL_SOCKET,SO_LINGER,&slg,sizeof(slg))<0) {
         (void) rou_alert(0,"%s Unable to set socket option "
                            "SO_LINGER for <%s> (error='%s')",
@@ -118,23 +128,6 @@ while (proceed==true) {
         phase=999;     //trouble cleanup phase
        }
       break;
-    case 4     :       /*getting socket option */
-      (void) soc_getlinger(handle,"binhandle");
-      if ((flags=fcntl(handle,F_GETFL,0))<0) {
-        (void) rou_alert(0,"%s Unable to set socket descriptor "
-                           "for <%s> (error='%s')",
-                          OPEP,ai->ai_canonname,strerror(errno));
-        phase=999;     //trouble cleanup phase
-       }
-      break;
-    case 5     :       //setting the socket working setting
-      if (fcntl(handle,F_SETFL,flags|O_NONBLOCK|O_ASYNC)<0) {
-        (void) rou_alert(0,"%s Unable to set socket in none "
-                           "block mode for <%s> (error='%s')",
-                          OPEP,ai->ai_canonname,strerror(errno));
-        phase=999;     //trouble cleanup phase
-       }
-      break;
     case 6     :       //getting socket option
       (void) soc_getlinger(handle,"before bind");
       if (bind(handle,ai->ai_addr,ai->ai_addrlen)<0) {
@@ -157,17 +150,15 @@ while (proceed==true) {
                           ai->ai_canonname,binding->port);
       proceed=false;    //evrything fine no need to go further
       break;
-    default    :       /*SAFE Guard            */
+    default    :       //SAFE Guard
       if (handle>=0)
         close(handle);
+      handle=-1;        //trouble trouble
       proceed=false;    
       break;
     }
   phase++;
   }
-(void) free(buf);
-(void) rou_alert(0,"JMPDBG got handle channel='%d'",handle);
-(void) soc_getlinger(handle,"exiting from bindhandle");
 return handle;
 #undef OPEP
 }
@@ -232,27 +223,18 @@ PUBLIC int soc_setlinger(int socket)
 
 {
 #define OPEP    "unisoc.c:soc_setlinger"
-#define BFSZ    30
 
 int status;
-int flags;
-char *buf;
 struct linger slg;
 
 status=-1;
 slg.l_onoff=true;
 slg.l_linger=0;
-buf=calloc(BFSZ,sizeof(char));
-flags=fcntl(socket,F_GETFL,0);
-(void) fcntl(socket,F_SETFL,flags|O_NONBLOCK|O_ASYNC);
-(void) setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,buf,BFSZ*sizeof(char));
-(void) setsockopt(socket,SOL_SOCKET,SO_REUSEPORT,buf,BFSZ*sizeof(char));
 status=setsockopt(socket,SOL_SOCKET,SO_LINGER,&slg,sizeof(slg));
 if (status<0)
   (void) rou_alert(0,"%s Unable to set socket option "
                      "SO_LINGER for <%s> (error='%s' bug?)",
                      OPEP,strerror(errno));
-(void) free(buf);
 return status;
 #undef  OPEP
 }
@@ -422,11 +404,12 @@ while (proceed==true) {
         soc=soc_onelisten(*bindings);
         (void) soc_getlinger(soc,"after onelisten");
         (*bindings)->handle=soc;
-        (void) soc_getlinger((*bindings)->handle,"after binding onelisten");
         if ((*bindings)->handle<0)
           ready=false;  //Trouble?
-        else
+        else {
+           (void) rou_alert(0,"JMPDBG mullisten ptr='%p",&((*bindings)->handle));
           (void) soc_getlinger((*bindings)->handle,"mullisten");
+          }
         bindings++;
         }
       break;
@@ -489,11 +472,12 @@ void soc_getlinger(int socket,char *inf)
 socklen_t len;
 struct linger slg;
 
+len=sizeof(struct linger);
 if (getsockopt(socket,SOL_SOCKET,SO_LINGER,&slg,&len)<0) 
   (void) rou_alert(0,"JMPDBG LISTEN trouble (error='%s')",strerror(errno));
 (void) rou_alert(0,"JMPDBG [%s] get socket='%d' linger.onoff='%d', "
-                   "timeout linger='%d'",
-                   inf,socket,slg.l_onoff,slg.l_linger);
+                   "timeout linger='%d' (len='%d')",
+                   inf,socket,slg.l_onoff,slg.l_linger,len);
 }
 /*
 ^L