newsoc->ip=strdup(soc->ip);
newsoc->port=strdup(soc->port);
newsoc->iteration=soc->iteration;
-newsoc->handle=-1;
+newsoc->handle=soc->handle;
return newsoc;
}
/*
*/
/********************************************************/
/* */
-/* Procedure to wait and get a new handle */
+/* Procedure to wait incoming connexion on a */
+/* plain (not crypted) socket */
/* */
/********************************************************/
static int getnewhandle(SOCTYP *soc)
int newhandle;
+(void) printf("JMPDBG soc handle='%d'\n",soc->handle);
if ((newhandle=accept(soc->handle,(SOCKADDR *)0,(socklen_t *)0))<0) {
if (errno==EAGAIN)
errno=EWOULDBLOCK;
*/
/********************************************************/
/* */
+/* Procedure to prepare plain incoming channel */
+/* */
+/********************************************************/
+static _Bool plainsoc(SOCTYP *soc)
+
+{
+#define OPEP "devsoc:plainsoc"
+
+_Bool good;
+int newhandle;
+int flags;
+int phase;
+_Bool proceed;
+
+good=false;
+newhandle=-1;
+flags=0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //First prepare a new socket
+ if ((newhandle=getnewhandle(soc))<0) {
+ phase=999; //no newhandle troub trouble
+ }
+ break;
+ case 1 : //getting newhandle flag
+ if ((flags=fcntl(newhandle,F_GETFL,0))<0) {
+ (void) rou_core_dump("%s, Unable to get socket descripteur on "
+ "IP/PORT <%s/%s> (Bug? error=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ phase=999; //never reached
+ }
+ break;
+ case 2 : //setting newhandle working mode
+ if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) {
+ (void) rou_core_dump("%s, Unable to set socket descripteur on "
+ "IP/PORT <%s/%s> (Bug? error=<%s>)",
+ OPEP,soc->ip,soc->port,strerror(errno));
+ phase=999; //never reached
+ }
+ break;
+ case 3 : //Socket ready
+ soc->handle=newhandle;
+ good=true;
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return good;
+#undef OPEP
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
+/* Procedure to wait and get a new handle */
+/* */
+/********************************************************/
+static SOCTYP *waitincoming(SOCTYP *soc)
+
+{
+#define OPEP "devsoc.c:waitincoming"
+
+SOCTYP *newsoc;
+_Bool ready;
+int phase;
+_Bool proceed;
+
+(void) printf("JMPDBG starting from waitincoming\n");
+newsoc=(SOCTYP *)0;
+ready=false;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //First prepare a new socket
+ newsoc=dupsocket(soc);
+ break;
+ case 1 : //wait for incoming connexion
+ switch (newsoc->proto) {
+ case pro_smtp : //plain socket
+ case pro_starttls : //plain socket + STARTTLS
+ ready=plainsoc(newsoc);
+ break;
+ case pro_smtps : //set secure socket
+ if ((newsoc->tls=tls_opentls(newsoc->handle,true))!=(TLSTYP *)0)
+ ready=tls_accept(newsoc->tls);
+ break;
+ default :
+ (void) rou_alert(0,"%s Protocol '%d' unset (Bug?)",
+ OPEP,(int)(newsoc->proto));
+ break;
+ }
+ break;
+ case 2 : //wait for incoming connexion
+ if (ready==false) {
+ newsoc=soc_release(newsoc); //trouble touble
+ }
+ break;
+ default : //SAFE guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+(void) printf("JMPDBG exit from waitincoming\n");
+return newsoc;
+#undef OPEP
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Procedure to bind a socket to a specific */
/* address and return the linked handle */
/* */
/* */
/* Procedure to wait an accept a connexion comming */
/* from a remote client. */
-/* return the handle */
+/* return a new socket. */
/* */
/********************************************************/
PUBLIC SOCPTR *soc_accept(SOCPTR *socptr,int pos)
#define OPEP "devsoc.c:soc_accept"
SOCTYP *newsoc;
-int newhandle;
SOCTYP *soc;
-int flags;
int phase;
_Bool proceed;
newsoc=(SOCTYP *)0;
-newhandle=-1;
soc=(SOCTYP *)socptr;
-flags=0;
phase=0;
proceed=true;
while (proceed==true) {
(void) prc_settitle("%s waiting on [%s:%s] (%02d/%02d)",
appname,soc->ip,soc->port,pos,soc->iteration);
break;
- case 2 : //getting the new handle
- if ((newhandle=getnewhandle(soc))<0) {
- newhandle=-1;
+ case 2 : //waiting for new connection
+ if ((newsoc=waitincoming(soc))==(SOCPTR *)0) {
+ (void) rou_core_dump("%s, Contact from Remote not successful",OPEP);
phase=999; //no need to go further
}
break;
- case 3 : //getting newhandle flag
- if ((flags=fcntl(newhandle,F_GETFL,0))<0) {
- (void) rou_core_dump("%s, Unable to get socket descripteur on "
- "IP/PORT <%s/%s> (Bug? error=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- phase=999; //never reached
- }
- break;
- case 4 : //setting newhandle working mode
- if ((flags=fcntl(newhandle,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0) {
- (void) rou_core_dump("%s, Unable to set socket descripteur on "
- "IP/PORT <%s/%s> (Bug? error=<%s>)",
- OPEP,soc->ip,soc->port,strerror(errno));
- phase=999; //never reached
- }
- break;
- case 5 : //preparing a new socket
- newsoc=dupsocket(soc);
- newsoc->handle=newhandle;
- break;
- case 6 : //configuring extra socket features
- switch (newsoc->proto) {
- case pro_smtp : //plain socket
- case pro_starttls : //plain socket + STARTTLS
- phase=999;
- break;
- case pro_smtps : //set secure socket
- if ((newsoc->tls=tls_opentls(newsoc->handle,true))==(TLSTYP *)0) {
- newsoc=soc_release(newsoc); //trouble trouble
- break;
- }
- (void) tls_check_peer(newsoc->tls);
- break;
- default : //undefined socket type???
- (void) rou_alert(0,"%s, Undefined socket protocol='%d' (Bug?)",
- OPEP,soc->proto);
- break;
- }
- break;
default : //SAFE guard
proceed=false;
break;
#include <openssl/x509v3.h>
#include <poll.h>
#include <stdio.h>
+#include <unistd.h>
#include "subrou.h"
#include "unitls.h"
good=true;
va_start(args,msg);
(void) vsnprintf(info,sizeof(info),msg,args);
+(void) rou_alert(0,"JMPDBG showtlserror sslerror='%d' code='%d'",
+ sslerror,SSL_get_error(tls->ssl,sslerror));
if (sslerror<=0) {
char *detail;
int code;
detail="syscall error";
break;
case SSL_ERROR_SSL :
- detail=ERR_error_string(ERR_get_error(),(char *)0);
+ (void) showerrorstack(info);
+ //detail=ERR_error_string(ERR_get_error(),(char *)0);
+ detail="Bigre";
break;
default :
(void) rou_alert(0,"%s, caused by <%s> Unexpected ssl error='%d'",
phase=0;
proceed=true;
while (proceed==true) {
- (void) fprintf(stderr,"JMPDBG set_server_certificate phase='%d'\n",phase);
switch (phase) {
case 0 : //load CA trusted file
if (SSL_CTX_use_certificate_chain_file(ctx,certpub[0])!=1) {
phase=0;
proceed=true;
while (proceed==true) {
- (void) fprintf(stderr,"JMPDBG tlsopentls phase='%d'\n",phase);
switch (phase) {
case 0 : //prepare the structure first;
tls=(TLSTYP *)calloc(1,sizeof(TLSTYP));
tls->handle=handle;
tls->server=server;
+ (void) SSL_library_init();
+ (void) SSL_load_error_strings();
+ (void) ERR_clear_error();
if ((tls->ctx=SSL_CTX_new(tls_methode()))==(SSL_CTX *)0) {
(void) showtlserror(tls,0,"Get CTX");
tls=freetls(tls);
PUBLIC int tls_write(TLSTYP *tls,char *buffer,int tosend)
{
+#define OPEP "unitls.c:tls_write"
+
int sent;
-sent=-1;
+sent=0;
+(void) printf("JMPDBG sending<%s>\n",buffer);
if (tls!=(TLSTYP *)0) {
- if ((sent=SSL_write(tls->ssl,buffer,tosend))<=0)
- (void) showtlserror(tls,sent,"Trouble to send data");
+ _Bool proceed;
+ int sofar;
+
+ proceed=true;
+ while (proceed==true) {
+ proceed=false;
+ sofar=SSL_write(tls->ssl,buffer,tosend);
+ switch (sent) {
+ case -1 : //trouble to write
+ switch (SSL_get_error(tls->ssl,-1)) {
+ case SSL_ERROR_WANT_READ : //"wanted" error
+ case SSL_ERROR_WANT_WRITE :
+ (void) usleep(1000);
+ proceed=true;
+ break;
+ default :
+ (void) showtlserror(tls,sofar,"%s Premature EOF with crypted link",
+ OPEP);
+ sent=-1;
+ break;
+ }
+ break;
+ case 0 : //no char sent
+ switch (SSL_get_error(tls->ssl,0)) {
+ case SSL_ERROR_SYSCALL : //EOF received?
+ tls->goteof=true;
+ if (ERR_get_error()!=0)
+ (void) rou_alert(0,"%s wrong EOF",OPEP);
+ break;
+ default :
+ (void) rou_alert(0,"%s Unexpected SSL_write error='%d'",
+ OPEP,SSL_get_error(tls->ssl,0));
+ (void) showtlserror(tls,0,"%s JMPDBG Check what is SSL",OPEP);
+ break;
+ }
+ (void) sleep(1);
+ break;
+ default : //some character sent
+ (void) printf("JMPDBG sofar '%d' sent='%d'\n",sofar,sent);
+ sent+=sofar;
+ if (sent<tosend)
+ proceed=true;
+ break;
+ }
+ }
}
return sent;
+#undef OPEP
}
/*
^L