--- /dev/null
+#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);
+ }
+ }
+}
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;
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++;
}
_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;
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)
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;
int handle;
struct linger slg;
-char *buf;
+int reuse;
int flags;
int phase;
_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) {
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')",
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) {
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
}
{
#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
}
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;
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