mirror of
https://repo.or.cz/socat.git
synced 2025-07-15 15:43:24 +00:00
Reworked IPAPP clients
This commit is contained in:
parent
63f67101f4
commit
7b26406d96
16 changed files with 1660 additions and 649 deletions
162
xio-openssl.c
162
xio-openssl.c
|
@ -238,13 +238,13 @@ static int xioopen_openssl_connect(
|
|||
int socktype = SOCK_STREAM;
|
||||
int ipproto = IPPROTO_TCP;
|
||||
bool dofork = false;
|
||||
union sockaddr_union us_sa, *us = &us_sa;
|
||||
socklen_t uslen = sizeof(us_sa);
|
||||
struct addrinfo **themarr, *themp;
|
||||
int maxchildren = 0;
|
||||
struct addrinfo **bindarr = NULL;
|
||||
struct addrinfo **themarr = NULL;
|
||||
uint16_t bindport = 0;
|
||||
bool needbind = false;
|
||||
bool lowport = false;
|
||||
int level = E_ERROR;
|
||||
int i;
|
||||
SSL_CTX* ctx;
|
||||
bool opt_ver = true; /* verify peer certificate */
|
||||
char *opt_cert = NULL; /* file name of client certificate */
|
||||
|
@ -254,7 +254,7 @@ static int xioopen_openssl_connect(
|
|||
int result;
|
||||
|
||||
if (!(xioflags & XIO_MAYCONVERT)) {
|
||||
Error("address with data processing not allowed here");
|
||||
Error1("%s: address with data processing not allowed here", argv[0]);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
sfd->flags |= XIO_DOESCONVERT;
|
||||
|
@ -272,14 +272,6 @@ static int xioopen_openssl_connect(
|
|||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
if (sfd->howtoend == END_UNSPEC)
|
||||
sfd->howtoend = END_SHUTDOWN;
|
||||
if (applyopts_single(sfd, opts, PH_INIT) < 0)
|
||||
return -1;
|
||||
applyopts(sfd, -1, opts, PH_INIT);
|
||||
|
||||
retropt_bool(opts, OPT_FORK, &dofork);
|
||||
|
||||
retropt_string(opts, OPT_OPENSSL_CERTIFICATE, &opt_cert);
|
||||
retropt_string(opts, OPT_OPENSSL_COMMONNAME, (char **)&opt_commonname);
|
||||
#if defined(HAVE_SSL_set_tlsext_host_name) || defined(SSL_set_tlsext_host_name)
|
||||
|
@ -315,73 +307,83 @@ static int xioopen_openssl_connect(
|
|||
socktype = SOCK_DGRAM;
|
||||
ipproto = IPPROTO_UDP;
|
||||
}
|
||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||
retropt_int(opts, OPT_SO_PROTOTYPE, &ipproto);
|
||||
|
||||
result =
|
||||
_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
||||
sfd->para.socket.ip.ai_flags,
|
||||
&themarr, us, &uslen,
|
||||
&needbind, &lowport, socktype);
|
||||
if (result != STAT_OK) return STAT_NORETRY;
|
||||
/* Apply and retrieve some options */
|
||||
result = _xioopen_ipapp_init(sfd, xioflags, opts,
|
||||
&dofork, &maxchildren,
|
||||
&pf, &socktype, &ipproto);
|
||||
if (result != STAT_OK)
|
||||
return result;
|
||||
|
||||
if (xioparms.logopt == 'm') {
|
||||
Info("starting connect loop, switching to syslog");
|
||||
diag_set('y', xioparms.syslogfac); xioparms.logopt = 'y';
|
||||
} else {
|
||||
Info("starting connect loop");
|
||||
}
|
||||
opts0 = opts; /* save remaining options for each loop */
|
||||
opts = NULL;
|
||||
|
||||
do { /* loop over failed connect and SSL handshake attempts */
|
||||
Notice2("opening OpenSSL connection to %s:%s", hostname, portname);
|
||||
|
||||
/* Loop over themarr (which had been "ai_sorted") */
|
||||
i = 0;
|
||||
themp = themarr[i++];
|
||||
while (themp != NULL) {
|
||||
do { /* loop over retries (failed connect and SSL handshake attempts) and/or forks */
|
||||
int _errno;
|
||||
|
||||
#if WITH_RETRY
|
||||
if (sfd->forever || sfd->retry || themarr[i] != NULL) {
|
||||
level = E_INFO;
|
||||
} else
|
||||
if (sfd->forever || sfd->retry) {
|
||||
level = E_NOTICE;
|
||||
} else
|
||||
#endif /* WITH_RETRY */
|
||||
level = E_ERROR;
|
||||
level = E_WARN;
|
||||
|
||||
/* This cannot fork because we retrieved fork option above */
|
||||
result =
|
||||
_xioopen_connect(sfd,
|
||||
needbind?us:NULL, uslen,
|
||||
themp->ai_addr, themp->ai_addrlen,
|
||||
opts, pf?pf:themp->ai_addr->sa_family, socktype, ipproto, lowport, level);
|
||||
if (result == STAT_OK)
|
||||
break;
|
||||
themp = themarr[i++];
|
||||
if (themp == NULL) {
|
||||
result = STAT_RETRYLATER;
|
||||
}
|
||||
}
|
||||
opts = copyopts(opts0, GROUP_ALL);
|
||||
|
||||
result =
|
||||
_xioopen_ipapp_prepare(&opts, opts0, hostname, portname,
|
||||
pf, socktype, ipproto,
|
||||
sfd->para.socket.ip.ai_flags,
|
||||
&themarr, &bindarr, &bindport, &needbind, &lowport);
|
||||
switch (result) {
|
||||
case STAT_OK: break;
|
||||
#if WITH_RETRY
|
||||
case STAT_RETRYLATER:
|
||||
case STAT_RETRYNOW:
|
||||
if (sfd->forever || sfd->retry) {
|
||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||
if (sfd->forever || sfd->retry--) {
|
||||
if (result == STAT_RETRYLATER)
|
||||
Nanosleep(&sfd->intervall, NULL);
|
||||
if (bindarr != NULL) xiofreeaddrinfo(bindarr);
|
||||
xiofreeaddrinfo(themarr);
|
||||
freeopts(opts);
|
||||
continue;
|
||||
}
|
||||
#endif /* WITH_RETRY */
|
||||
case STAT_NORETRY:
|
||||
if (bindarr != NULL) xiofreeaddrinfo(bindarr);
|
||||
xiofreeaddrinfo(themarr);
|
||||
freeopts(opts);
|
||||
freeopts(opts0);
|
||||
return result;
|
||||
}
|
||||
|
||||
Notice2("opening connection to server %s:%s", hostname, portname);
|
||||
result =
|
||||
_xioopen_ipapp_connect(sfd, hostname, opts, themarr,
|
||||
needbind, bindarr, bindport, lowport, level);
|
||||
_errno = errno;
|
||||
if (bindarr != NULL) xiofreeaddrinfo(bindarr);
|
||||
xiofreeaddrinfo(themarr);
|
||||
switch (result) {
|
||||
case STAT_OK: break;
|
||||
#if WITH_RETRY
|
||||
case STAT_RETRYLATER:
|
||||
case STAT_RETRYNOW:
|
||||
if (sfd->forever || sfd->retry--) {
|
||||
if (result == STAT_RETRYLATER) {
|
||||
Nanosleep(&sfd->intervall, NULL);
|
||||
}
|
||||
--sfd->retry;
|
||||
freeopts(opts);
|
||||
continue;
|
||||
}
|
||||
xiofreeaddrinfo(themarr);
|
||||
return STAT_NORETRY;
|
||||
#endif /* WITH_RETRY */
|
||||
default:
|
||||
xiofreeaddrinfo(themarr);
|
||||
return result;
|
||||
}
|
||||
/*! isn't this too early? */
|
||||
if ((result = _xio_openlate(sfd, opts)) < 0) {
|
||||
xiofreeaddrinfo(themarr);
|
||||
Error4("%s:%s:%s: %s", argv[0], hostname, portname,
|
||||
_errno?strerror(_errno):"(See above)");
|
||||
freeopts(opts0);
|
||||
freeopts(opts);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -392,19 +394,19 @@ static int xioopen_openssl_connect(
|
|||
#if WITH_RETRY
|
||||
case STAT_RETRYLATER:
|
||||
case STAT_RETRYNOW:
|
||||
if (sfd->forever || sfd->retry) {
|
||||
Close(sfd->fd);
|
||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||
if (sfd->forever || sfd->retry--) {
|
||||
if (result == STAT_RETRYLATER) {
|
||||
Nanosleep(&sfd->intervall, NULL);
|
||||
}
|
||||
--sfd->retry;
|
||||
freeopts(opts);
|
||||
Close(sfd->fd);
|
||||
continue;
|
||||
}
|
||||
#endif /* WITH_RETRY */
|
||||
default:
|
||||
xiofreeaddrinfo(themarr);
|
||||
return STAT_NORETRY;
|
||||
freeopts(opts);
|
||||
freeopts(opts0);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (dofork) {
|
||||
|
@ -419,15 +421,19 @@ static int xioopen_openssl_connect(
|
|||
level = E_WARN;
|
||||
}
|
||||
while ((pid = xio_fork(false, level, sfd->shutup)) < 0) {
|
||||
if (sfd->forever || --sfd->retry) {
|
||||
Nanosleep(&sfd->intervall, NULL); continue;
|
||||
if (sfd->forever || sfd->retry--) {
|
||||
Nanosleep(&sfd->intervall, NULL);
|
||||
freeopts(opts);
|
||||
continue;
|
||||
}
|
||||
xiofreeaddrinfo(themarr);
|
||||
freeopts(opts);
|
||||
freeopts(opts0);
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
|
||||
if (pid == 0) { /* child process */
|
||||
sfd->forever = false; sfd->retry = 0;
|
||||
sfd->forever = false;
|
||||
sfd->retry = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -437,21 +443,29 @@ static int xioopen_openssl_connect(
|
|||
sfd->para.openssl.ssl = NULL;
|
||||
/* with and without retry */
|
||||
Nanosleep(&sfd->intervall, NULL);
|
||||
dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL);
|
||||
while (maxchildren > 0 && num_child >= maxchildren) {
|
||||
Info1("all %d allowed children are active, waiting", maxchildren);
|
||||
Nanosleep(&sfd->intervall, NULL);
|
||||
}
|
||||
freeopts(opts);
|
||||
continue; /* with next socket() bind() connect() */
|
||||
}
|
||||
#endif /* WITH_RETRY */
|
||||
break;
|
||||
|
||||
} while (true); /* drop out on success */
|
||||
xiofreeaddrinfo(themarr);
|
||||
|
||||
openssl_conn_loginfo(sfd->para.openssl.ssl);
|
||||
|
||||
free((void *)opt_commonname);
|
||||
free((void *)opt_snihost);
|
||||
|
||||
/* fill in the fd structure */
|
||||
return STAT_OK;
|
||||
Notice2("successfully connected to SSL server %s:%s", hostname, portname);
|
||||
|
||||
result = _xio_openlate(sfd, opts);
|
||||
freeopts(opts);
|
||||
freeopts(opts0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue