19#include <openssl/err.h>
23#include "../include/Syncmsg.h"
25#include <isode/messages/base.h>
26#include <isode/base/crypto.h>
31#define MAXSOCKADDRLEN 1024
66 struct sockaddr_storage _caddr;
68 struct sockaddr_storage _laddr;
71 const char * _hostname;
88 inline bool checkUser () {
90 MSG_IOevent_MissingUser_LOG ();
97 inline bool wouldBlock () {
98 return ( errno == EWOULDBLOCK || errno == EAGAIN );
102 inline void waitEvent (
unsigned events);
106 inline bool doRead ();
110 inline bool doWrite ();
113 inline void doAccept ();
119 inline int doTLSread();
123 inline int doTLSwrite();
127 inline int doTLShandshake();
131 inline int doTLSshutdown();
134 inline bool setTrafficClass (
137 unsigned traffic_class);
147 _state (State_noconnect),
171 if ( _poller != 0 ) {
177 int err = SSL_get_error(_ssl, 0);
178 if (err != SSL_ERROR_NONE) {
180 LOG_DEBUG ((
"SocketPoll::tidy() - SSL error (%d)", err));
186 _fd = INVALID_ENDPOINT;
189 }
else if (
_fd != INVALID_ENDPOINT ) {
190 if ( _poller != 0 ) {
199 shutdown (
_fd, SHUT_WR);
202 _fd = INVALID_ENDPOINT;
211 _state = State_noconnect;
221 if ( SetHandleInformation ((HANDLE)
_fd,
223 HANDLE_FLAG_INHERIT) == 0 ) {
224 MSG_IOevent_Inherit_LOG();
227#elif defined (FD_CLOEXEC)
228 int flags = fcntl (
_fd, F_GETFD, 0);
231 flags &= ~FD_CLOEXEC;
232 if ( fcntl (
_fd, F_SETFD, flags) != 0 ) {
233 MSG_IOevent_Inherit_LOG ();
251 if (
_fd == INVALID_ENDPOINT ) {
252 MSG_IOevent_NotConnected_SET (msp);
253 return MSG_IOevent_NotConnected;
256#ifdef GETSOCKNAME_NEEDS_INTP
262 if ( getsockname (
_fd, laddr, &lalen) != 0 ) {
264 MSG_IOevent_IOerror_SET (msp,
"getsockname");
265 return MSG_IOevent_IOerror;
269 *lalenp = convert2ipv4 (laddr, lalen);
278 if (
_fd == INVALID_ENDPOINT ) {
279 MSG_IOevent_NotConnected_SET (msp);
280 return MSG_IOevent_NotConnected;
283#ifdef GETPEERNAME_NEEDS_INTP
289 if ( getpeername (
_fd, laddr, &lalen) != 0 ) {
291 MSG_IOevent_IOerror_SET (msp,
"getpeername");
292 return MSG_IOevent_IOerror;
296 *lalenp = convert2ipv4 (laddr, lalen);
302 if ( _state != State_tls || _ssl == 0 )
303 return TLS_NULL_WITH_NULL_NULL;
305 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
306 return SSLTLS::cipher_id(cipher);
311 if ( _state != State_tls || _ssl == 0 )
314 return SSL_get_peer_certificate(_ssl);
505inline void Stream::SocketPoll::waitEvent (
unsigned events)
507 StatusIndication statusind (
this);
509 if (
_fd == INVALID_ENDPOINT )
512 if ( _poller == 0 ) {
515 if ( _poller == 0 ) {
516 MSG_IOevent_NoPollProvider_SET (&statusind.msg);
525 MSG_IOevent_PollRegister_SET (&statusind.msg, rc);
540bool Stream::SocketPoll::doWrite ()
542 ssize_t remain = (ssize_t)_wlen - (_wptr - _wbuf);
543 ssize_t tosend = remain;
546 LOG_DEBUG ((
"SocketPoll::doWrite() - send %ld", (
long)tosend));
549 nbytes = send (_fd, _wptr, tosend, 0);
552 StatusIndication statusind (
this);
556 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
568 if (errno == ENOBUFS) {
571 LOG_DEBUG ((
"SocketPoll::doWrite() - retry send with %d", tosend));
574 if ((tosend == 0) || (errno != ENOBUFS)) {
576 MSG_IOevent_IOerror_SET (&statusind.msg,
"send");
582 MSG_IOevent_IOerror_SET (&statusind.msg,
"send");
587 GetUser()->Deliver (&statusind);
604 release.len = _wptr - _wbuf;
609 GetUser()->Deliver (&release);
619bool Stream::SocketPoll::doRead ()
621 ssize_t remain = (ssize_t)_rlen - (_rptr - _rbuf);
623 LOG_DEBUG ((
"doRead: _rlen=%d remain=%d", (
int)_rlen, (
int)remain));
625 ssize_t nbytes = recv (_fd, _rptr, remain, 0);
627 LOG_DEBUG ((
"doRead: recv -> %d", (
int)nbytes));
630 StatusIndication statusind (
this);
634 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
644 MSG_IOevent_IOerror_SET (&statusind.msg,
"recv");
647 GetUser()->Deliver (&statusind);
655 if ( nbytes == remain )
661 LOG_DEBUG ((
"doRread: remain=%d _rfill=%d", (
int)remain, _rfill));
665 if ( !_rfill || remain == 0 ) {
666 DataIndication dataind;
669 dataind.len = _rptr - _rbuf;
674 GetUser()->Deliver (&dataind);
683void Stream::SocketPoll::doAccept ()
685 StatusIndication statusind (
this);
686 char abuf[MAXSOCKADDRLEN];
687#ifdef ACCEPT_NEEDS_INTP
694 endpoint_t newfd = accept (_fd, (
struct sockaddr *)abuf, &alen);
695 if (INVALID_ENDPOINT == newfd) {
703 MSG_IOevent_AcceptError_SET (&statusind.msg);
704 MSGappendsyserror (&statusind.msg);
705 GetUser()->Deliver (&statusind);
711 MSG_IOevent_AcceptError_SET (&statusind.msg);
712 MSGappendsyserror (&statusind.msg);
713 GetUser()->Deliver (&statusind);
717 if ( _emfile > 100 ) _emfile = 100;
719 _timer.Sendms (100*_emfile, dummy);
735 MSG_IOevent_IOerror_SET (&statusind.msg,
"accept");
736 GetUser()->Deliver (&statusind);
746#if defined(EWOULDBLOCK)
747# if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
758 if ( SetHandleInformation(
762 MSG_IOevent_Inherit_LOG();
764#elif defined (FD_CLOEXEC)
765 (void) fcntl(newfd, F_SETFD, FD_CLOEXEC);
768 bool do_setsockopt =
true;
770 if ( fcntl(newfd, F_SETFL, O_NONBLOCK) != 0 ) {
772 MSG_IOevent_IoctlError_SET(&statusind.msg);
773 MSGappendsyserror(&statusind.msg);
774 GetUser()->Deliver(&statusind);
775 do_setsockopt =
false;
777#elif defined(FIONBIO)
779 if ( ioctl(newfd, FIONBIO, &onoff) != 0 ) {
781 MSG_IOevent_IoctlError_SET(&statusind.msg);
782 MSGappendsyserror(&statusind.msg);
783 GetUser()->Deliver(&statusind);
784 do_setsockopt =
false;
787#error Cannot set socket into non-blocking more
798 setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
sizeof nodelay);
806 setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE, (
char *)&keepalive,
sizeof keepalive);
811 connind.listener =
this;
814 newprov->
_fd = newfd;
815 newprov->_state = State_accepting;
817 memcpy(&newprov->_caddr, abuf, alen);
818 newprov->_clen = alen;
820 connind.
saddr =
reinterpret_cast<struct sockaddr *
>(&newprov->_caddr);
821 connind.
salen = convert2ipv4(
reinterpret_cast<struct sockaddr *
>(&newprov->_caddr), alen);
823#ifdef GETSOCKNAME_NEEDS_INTP
828 llen =
sizeof newprov->_laddr;
829 newprov->_llen =
sizeof newprov->_laddr;
831 getsockname(newfd,
reinterpret_cast<struct sockaddr *
>(&newprov->_laddr), &llen);
833 newprov->_llen = llen;
835 connind.
laddr =
reinterpret_cast<struct sockaddr *
>(&newprov->_laddr);
836 connind.
lalen = newprov->_llen;
838 GetUser()->Deliver(&connind);
846 waitEvent (::Poll::Event_In);
850int Stream::SocketPoll::doTLSread ()
852 int remain = (int)_rlen - (_rptr - _rbuf);
854 LOG_DEBUG ((
"doTLSread: _rlen=%d remain=%d", (
int)_rlen, (
int)remain));
856 int nbytes = SSL_read (_ssl, _rptr, remain);
858 LOG_DEBUG ((
"doTLSread: SSL_read -> %d", nbytes));
865 StatusIndication statusind (
this);
867 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
869 GetUser()->Deliver (&statusind);
871 _tlsstate = TLS_idle;
878 if ( nbytes == remain )
884 LOG_DEBUG ((
"doRread: remain=%d _rfill=%d", (
int)remain, _rfill));
888 if ( !_rfill || remain == 0 ) {
889 DataIndication dataind;
892 dataind.len = _rptr - _rbuf;
897 _tlsstate = TLS_idle;
899 GetUser()->Deliver (&dataind);
905int Stream::SocketPoll::doTLSwrite ()
907 int remain = (int)_wlen - (_wptr - _wbuf);
909 int nbytes = SSL_write (_ssl, _wptr, remain);
922 release.len = _wptr - _wbuf;
927 GetUser()->Deliver (&release);
929 _tlsstate = TLS_idle;
935int Stream::SocketPoll::doTLShandshake ()
937 int rc = SSL_do_handshake (_ssl);
942 StatusIndication statusind (
this);
945 _tlsstate = TLS_idle;
950 _tlsstate = TLS_idle;
952 const char *version = SSL_get_version(_ssl);
954 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
955 TLS_CipherSuite cs = SSLTLS::cipher_id(cipher);
956 int strength = SSL_CIPHER_get_bits(cipher, NULL);
958 X509 *peer = SSL_get_peer_certificate(_ssl);
965 if ( _choice == SSLTLS::tls_verify_require ) {
966 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
967 MSG_IOevent_SSLnocert_SET (&submsg);
968 MSGappend (&statusind.msg, &submsg);
971 MSG_IOevent_SSLOK_SET (&statusind.msg,
972 version, cs, strength);
977 }
else if ( _choice == SSLTLS::tls_verify_none ) {
978 MSG_IOevent_SSLOK_SET (&statusind.msg,
979 version, cs, strength);
985 X509_NAME *subject_name = X509_get_subject_name(peer);
987 long result = SSL_get_verify_result(_ssl);
988 char *peername = X509_NAME_to_text (subject_name);
993 MSG_IOevent_SSLverified_SET (&statusind.msg,
994 version, cs, strength,
998 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
999 MSG_IOevent_SSLnoissuercert_SET (&submsg);
1001 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1002 MSG_IOevent_SSLcertdecryptfailed_SET (&submsg);
1004 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1005 MSG_IOevent_SSLcertsignature_SET (&submsg);
1007 case X509_V_ERR_CERT_NOT_YET_VALID:
1008 MSG_IOevent_SSLcertnotyetvalid_SET (&submsg);
1010 case X509_V_ERR_CERT_HAS_EXPIRED:
1011 MSG_IOevent_SSLcertexpired_SET (&submsg);
1013 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1014 MSG_IOevent_SSLcertnotbefore_SET (&submsg);
1016 case X509_V_ERR_OUT_OF_MEM:
1017 MSG_Base_Nomem_SET (&submsg, 0);
1019 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1020 MSG_IOevent_SSLselfsigned_SET (&submsg);
1022 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1023 MSG_IOevent_SSLlocalissuer_SET (&submsg);
1025 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1026 MSG_IOevent_SSLleafsignature_SET (&submsg);
1028 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1029 MSG_IOevent_SSLchaintoolong_SET (&submsg);
1031 case X509_V_ERR_INVALID_CA:
1032 MSG_IOevent_SSLinvalidCA_SET (&submsg);
1034 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1035 MSG_IOevent_SSLpathlength_SET (&submsg);
1037 case X509_V_ERR_INVALID_PURPOSE:
1038 MSG_IOevent_SSLinvalidpurpose_SET (&submsg);
1040 case X509_V_ERR_CERT_UNTRUSTED:
1041 MSG_IOevent_SSLuntrusted_SET (&submsg);
1043 case X509_V_ERR_CERT_REJECTED:
1044 MSG_IOevent_SSLrejected_SET (&submsg);
1046 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
1047 MSG_IOevent_SSLsubjectissuer_SET (&submsg);
1049 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
1050 MSG_IOevent_SSLserialmismatch_SET (&submsg);
1052 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
1053 MSG_IOevent_SSLkeyusage_SET (&submsg);
1056 MSG_IOevent_SSLunknown_SET (&submsg, result);
1061 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
1062 MSGappend (&statusind.msg, &submsg);
1065 if (x509_acceptable_name(subject_name) != OK) {
1067 MSG_IOevent_SSLnul_in_subject_LOG(peername);
1070 if ( peername != 0 )
1075 if (!closing && _hostname &&
1076 SSLTLS::CheckHostname (peer, _hostname, &statusind.msg) != OK ) {
1083 _tlsstate = TLS_idle;
1085 GetUser()->Deliver (&statusind);
1093int Stream::SocketPoll::doTLSshutdown ()
1095 int rc = SSL_shutdown (_ssl);
1099 LOG_DEBUG ((
"SocketPoll::doTLSshutdown() - shutdown in progress"));
1101 int err = SSL_get_error(_ssl, rc);
1102 LOG_DEBUG ((
"SocketPoll::doTLSshutdown() - SSL error (%d)", err));
1109 StatusIndication statusind (
this);
1110 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1111 GetUser()->Deliver (&statusind);
1114 _tlsstate = TLS_idle;
1120void Stream::SocketPoll::doTLS ()
1129 switch ( _tlsstate ) {
1132 _tlsstate = TLS_write;
1135 }
else if ( _rlen != 0 ) {
1148 rc = doTLShandshake();
1152 rc = doTLSshutdown();
1156 if ( rc > 0 )
continue;
1158 StatusIndication statusind (
this);
1160 switch (SSL_get_error(_ssl, rc)) {
1161 case SSL_ERROR_NONE:
1165 case SSL_ERROR_ZERO_RETURN:
1167 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1170 case SSL_ERROR_WANT_READ:
1171 waitEvent (::Poll::Event_In);
1174 case SSL_ERROR_WANT_WRITE:
1175 waitEvent (::Poll::Event_Out);
1178 case SSL_ERROR_SYSCALL:
1180 if (ERR_get_error()==0) {
1183 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1185 MSG_IOevent_IOerror_SET (&statusind.msg,
"SSL");
1188 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_ERROR_SYSCALL");
1193 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_ERROR_SSL");
1196 case SSL_ERROR_WANT_CONNECT:
1197 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_WANT_CONNECT");
1200 case SSL_ERROR_WANT_ACCEPT:
1201 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_WANT_ACCEPT");
1207 snprintf (buf,
sizeof buf,
"err=%d", SSL_get_error(_ssl, rc));
1208 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, buf);
1213 GetUser()->Deliver (&statusind);
1222 waitEvent (::Poll::Event_In);
1227 if ( checkUser() )
return;
1231 LOG_DEBUG ((
"SocketPoll::actualDeliver (pollmsg = %x) state=%d",
1232 msg->events, _state));
1237 if ( (msg->events & ::Poll::Event_Terminate) ) {
1243 _fd = INVALID_ENDPOINT;
1247 MSG_IOevent_Terminating_SET (&statusind.msg);
1248 GetUser()->Deliver (&statusind);
1254 (::Poll::Event_Err | ::Poll::Event_Hup | ::Poll::Event_Nval) ) {
1261#ifdef GETSOCKOPT_NEEDS_INTP
1269 int rc = getsockopt (_fd, SOL_SOCKET, SO_ERROR, (
char *)&eno, &olen);
1271 const char *argv[1];
1274 MSGsetv (&statusind.msg, MSG_IOevent_IOerror, 1, argv);
1279 MSGID_BUILD(MSGLEVEL_ERROR, MSGID_SYSFAC, eno),
1281 MSGappend (&statusind.msg, &sockerr);
1283 MSGappendsyserror (&statusind.msg);
1286 GetUser()->Deliver (&statusind);
1294 _uevents &= ~msg->events;
1296 if ( msg->events & ::Poll::Event_In ) {
1303 case State_connected:
1304 LOG_DEBUG ((
"Read stuff: _rlen = %d", (
int)_rlen));
1308 waitEvent (::Poll::Event_In);
1312 case State_listening:
1321 if ( msg->events & ::Poll::Event_Out ) {
1328 case State_connected:
1332 waitEvent (::Poll::Event_Out);
1336 case State_connecting:
1337 _state = State_connected;
1338 MSG_IOevent_Connected_SET (&statusind.msg);
1339 GetUser()->Deliver (&statusind);
1347 if ( (_uevents & ~_pevents) && _poller )
1348 _poller->Control (
this);
1353 if ( checkUser() )
return;
1357 LOG_DEBUG ((
"SocketPoll::actualDeliver (External)"));
1359 if ( _state != State_noconnect ) {
1360 MSG_IOevent_NotConnected_SET (&statusind.msg);
1361 GetUser()->Deliver (&statusind);
1368 _state = State_listening;
1370 waitEvent (::Poll::Event_In);
1373 _state = State_connected;
1379 if ( checkUser() )
return;
1383 LOG_DEBUG ((
"SocketPoll::actualDeliver (ConnectRequest)"));
1385 if ( _state != State_noconnect ) {
1386 MSG_IOevent_NotConnected_SET (&statusind.msg);
1387 GetUser()->Deliver (&statusind);
1392#if defined(AF_INET6) && defined(PF_INET6)
1393 struct sockaddr_in6 ipv6addr;
1396 switch ( req->daddr->sa_family ) {
1397#if defined(AF_UNIX) && defined(PF_UNIX)
1407#if defined(AF_INET6) && defined(PF_INET6)
1410 if ( req->
dscp != 0 ) {
1412 ipv6addr = *
reinterpret_cast<const struct sockaddr_in6 *
>
1417 ipv6addr.sin6_flowinfo = htonl (req->
dscp << 22);
1419 req->daddr =
reinterpret_cast<struct sockaddr *
>(&ipv6addr);
1425 MSG_IOevent_AddrType_SET (&statusind.msg, req->daddr->sa_family);
1426 GetUser()->Deliver (&statusind);
1430 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1432 if ( fd == INVALID_ENDPOINT ) {
1433 MSG_IOevent_IOerror_SET (&statusind.msg,
"socket");
1434 GetUser()->Deliver (&statusind);
1440 if ( SetHandleInformation ((HANDLE)fd,
1441 HANDLE_FLAG_INHERIT,
1443 MSG_IOevent_Inherit_LOG ();
1445#elif defined (FD_CLOEXEC)
1446 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1450 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1451 MSG_IOevent_IOerror_SET (&statusind.msg,
"fcntl");
1452 GetUser()->Deliver (&statusind);
1456#elif defined (FIONBIO)
1458 if ( ioctl (fd, FIONBIO, &onoff) != 0 ) {
1459 MSG_IOevent_IOerror_SET (&statusind.msg,
"ioctl");
1460 GetUser()->Deliver (&statusind);
1465# error Cannot set socket into non-blocking more
1477 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
sizeof nodelay);
1486 setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,
1487 (
char *)&keepalive,
sizeof keepalive);
1491 if ( req->
dscp != 0 && !setTrafficClass (fd, family, req->
dscp) ) {
1492 MSG_IOevent_IOerror_SET (&statusind.msg,
"traffic class");
1493 GetUser()->Deliver (&statusind);
1500 MSG_IOevent_IOerror_SET (&statusind.msg,
"bind calling address");
1501 GetUser()->Deliver (&statusind);
1506 if ( connect (fd, req->daddr, req->
dalen) != 0 ) {
1508 if ( errno == EINPROGRESS || wouldBlock () ) {
1511 _state = State_connecting;
1514 waitEvent (::Poll::Event_Out);
1517 MSG_IOevent_IOerror_SET (&statusind.msg,
"connect");
1518 GetUser()->Deliver (&statusind);
1526 _state = State_connected;
1528 MSG_IOevent_Connected_SET (&statusind.msg);
1529 GetUser()->Deliver (&statusind);
1533bool Stream::SocketPoll::setTrafficClass (
1536 unsigned traffic_class)
1538 if ( family == PF_INET ) {
1541 int tosbyte = traffic_class << 2;
1544# define TOSLEVEL SOL_IP
1546# define TOSLEVEL IPPROTO_IP
1548 return setsockopt (fd, TOSLEVEL, IP_TOS,
1549 (
char *)&tosbyte,
sizeof tosbyte) == 0;
1561 if ( checkUser() )
return;
1565 LOG_DEBUG ((
"SocketPoll::actualDeliver (ListenRequest)"));
1567 if ( _state != State_noconnect ) {
1568 MSG_IOevent_NotConnected_SET (&statusind.msg);
1570 GetUser()->Deliver (&statusind);
1577 switch ( req->laddr->sa_family ) {
1588#if defined(AF_INET6) && defined(PF_INET6)
1595 MSG_IOevent_AddrType_SET (&statusind.msg, req->laddr->sa_family);
1596 GetUser()->Deliver (&statusind);
1600 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1602 if ( fd == INVALID_ENDPOINT ) {
1603 MSG_IOevent_IOerror_SET (&statusind.msg,
"socket");
1604 GetUser()->Deliver (&statusind);
1608#if defined(PF_INET6) && defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
1609 if ( family == PF_INET6 ) {
1612 if ( setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY,
1613 (
char *)&v6only,
sizeof v6only) != 0 ) {
1614 MSG_IOevent_IOerror_SET (&statusind.msg,
"setsockopt");
1615 GetUser()->Deliver (&statusind);
1622#if !defined(IC_WIN32) && defined(SO_REUSEADDR)
1625 if ( setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
1626 (
char *)&onoff,
sizeof onoff) != 0 ) {
1627 MSG_IOevent_IOerror_SET (&statusind.msg,
"setsockopt");
1628 GetUser()->Deliver (&statusind);
1634 if ( bind (fd, req->laddr, req->
lalen ) != 0 ) {
1635 MSG_IOevent_IOerror_SET (&statusind.msg,
"bind");
1636 GetUser()->Deliver (&statusind);
1643 if ( SetHandleInformation ((HANDLE)fd,
1644 HANDLE_FLAG_INHERIT,
1646 MSG_IOevent_Inherit_LOG ();
1648#elif defined (FD_CLOEXEC)
1649 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1653 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1654 MSG_IOevent_IOerror_SET (&statusind.msg,
"fcntl");
1655 GetUser()->Deliver (&statusind);
1659#elif defined (FIONBIO)
1661 if ( ioctl (fd, FIONBIO, &con) != 0 ) {
1662 MSG_IOevent_IOerror_SET (&statusind.msg,
"ioctl");
1663 GetUser()->Deliver (&statusind);
1668# error Cannot set socket into non-blocking more
1671 if ( listen (fd, req->
backlog ? req->
backlog : SOMAXCONN) != 0 ) {
1672 MSG_IOevent_IOerror_SET(&statusind.msg,
"listen");
1673 GetUser()->Deliver (&statusind);
1680 _state = State_listening;
1683 waitEvent (::Poll::Event_In);
1688 if ( checkUser() )
return;
1692 LOG_DEBUG ((
"SocketPoll::actualDeliver (ConnectAccept)"));
1694 if ( _fd == INVALID_ENDPOINT || _state != State_accepting ) {
1695 MSG_IOevent_NotConnected_SET (&statusind.msg);
1697 GetUser()->Deliver (&statusind);
1703 _state = State_connected;
1708 if ( checkUser() )
return;
1710 StatusIndication statusind (
this);
1712 LOG_DEBUG ((
"SocketPoll::actualDeliver (DisconnectRequest)"));
1715 case State_connected:
1716 case State_accepting:
1718 if ( _fd != INVALID_ENDPOINT )
1723 MSG_IOevent_NotConnected_SET (&statusind.msg);
1724 GetUser()->Deliver (&statusind);
1728 if ( _state == State_tls ) {
1729 _tlsstate = TLS_close;
1736 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1737 GetUser()->Deliver (&statusind);
1745 if ( checkUser() )
return;
1749 LOG_DEBUG ((
"SocketPoll::actualDeliver (DataRequest) state=%d _wlen=%ld",
1750 _state, (
long)_wlen));
1753 case State_connected:
1755 if ( _fd != INVALID_ENDPOINT )
1760 MSG_IOevent_NotConnected_SET (&statusind.msg);
1761 GetUser()->Deliver (&statusind);
1766 if ( req->buf == 0 || req->
len == 0 ) {
1767 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
1772 GetUser()->Deliver (&statusind);
1780 release.buf = req->buf;
1783 GetUser()->Deliver (&release);
1785 MSG_IOevent_DupWrite_SET (&statusind.msg);
1787 GetUser()->Deliver (&statusind);
1792 _wbuf = _wptr = req->buf;
1795 if ( _state == State_connected ) {
1796 if ( !doWrite () ) {
1798 waitEvent (::Poll::Event_Out);
1808 if ( checkUser() )
return;
1813 LOG_DEBUG ((
"SocketPoll::actualDeliver (ReadRequest)"));
1816 case State_connected:
1818 if ( _fd != INVALID_ENDPOINT )
1823 MSG_IOevent_NotConnected_SET (&statusind.msg);
1824 GetUser()->Deliver (&statusind);
1828 if ( req->buf == 0 || req->
len == 0 ) {
1829 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
1834 GetUser()->Deliver (&statusind);
1840 dataind.buf = req->buf;
1843 GetUser()->Deliver (&dataind);
1845 MSG_IOevent_DupRead_SET (&statusind.msg);
1847 GetUser()->Deliver (&statusind);
1852 _rbuf = _rptr = req->buf;
1856 LOG_DEBUG ((
"ReadRequest: _rbuf=%p _rlen=%d _rfill=%d",
1857 _rbuf, (
int)_rlen, _rfill));
1859 if ( _state == State_connected ) {
1864 if ( _rfull && doRead () )
1868 waitEvent (::Poll::Event_In);
1877 if ( checkUser() )
return;
1879 LOG_DEBUG ((
"SocketPoll::actualDeliver (StartTLS)"));
1885 MSG_IOevent_SSLalready_SET (&statusind.msg);
1886 GetUser()->Deliver (&statusind);
1889 case State_connected:
1890 if ( _fd != INVALID_ENDPOINT )
1895 MSG_IOevent_NotConnected_SET (&statusind.msg);
1896 GetUser()->Deliver (&statusind);
1903 SSLTLS::OpenSSLContext *sslctx =
1904 dynamic_cast<SSLTLS::OpenSSLContext *
>(req->context);
1906 _ssl = sslctx ? sslctx->GetSSL(_choice) : NULL;
1908 MSG_IOevent_SSLerror_SET (&statusind.msg,
"SSL_new",
"this returned NULL. No ID configured?");
1909 GetUser()->Deliver (&statusind);
1914 int err = SSL_get_error(_ssl, 0);
1915 if (err != SSL_ERROR_NONE) {
1917 LOG_DEBUG ((
"SocketPoll::actualDeliver(StartTLS) - SSL error code %d", err));
1921 BIO *bio = BIO_new_socket (_fd, TRUE);
1923 SSL_set_bio(_ssl, bio, bio);
1926 SSL_set_connect_state (_ssl);
1928 SSL_set_accept_state (_ssl);
1931 _tlsstate = TLS_handshake;
1938 if ( checkUser() )
return;
1940 LOG_DEBUG ((
"SocketPoll::actualDeliver (StreamControl)"));
1944 if ( _fd == INVALID_ENDPOINT ) {
1945 MSG_IOevent_NotConnected_SET (&statusind.msg);
1946 GetUser()->Deliver (&statusind);
1953 switch ( option->option ) {
1954#if defined(TCP_NODELAY)
1955 case StreamControlNoDelay:
1956 level = IPPROTO_TCP;
1963 name = SO_KEEPALIVE;
1978 MSG_IOevent_UnknownStreamOpt_SET (&statusind.msg, option->option);
1979 GetUser()->Deliver (&statusind);
1983 int rc = setsockopt (_fd, level, name, (
char *)&option->
value,
sizeof option->
value);
1985 MSG_IOevent_IOerror_SET (&statusind.msg,
"setsockopt");
1986 GetUser()->Deliver (&statusind);
tls_verify_client_choice
Values for choosing client verification.
virtual int Register(User *user)=0
Register an endpoint.
virtual void Deregister(User *user)=0
Deregister endpoint.
virtual void Control(User *user)=0
Set the events which are interesting for end point.
static Provider * GetPollService()
Implement as a singleton.
Poll user object interface.
unsigned _pevents
FD for this user.
endpoint_t _fd
Event to User.
unsigned _uevents
Provider's view of events.
Provider of a stream interface.
User * GetUser()
get the user
void SetUser(User *u)
set the user
Stream provider using sockets and using poll.
virtual int GetPeerAddress(struct sockaddr *laddr, socklen_t *lalenp, MSGstruct *msp)
Get the peer address.
virtual void Deliver(ConnectRequest *req)
connect
virtual void Deliver(::Poll::pollmsg *msg)
Deliver events to Poll provider.
virtual void Deliver(time_t *msg)
Handle timer event.
virtual SocketPoll * Clone()=0
Make another provider like this one.
void tidy()
Tidy up - close connections etc.
virtual int GetLocalAddress(struct sockaddr *laddr, socklen_t *lalenp, MSGstruct *msp)
Get the local address.
void actualDeliver(time_t *msg)
Handle timer event.
virtual void Deliver(ListenRequest *req)
listen
virtual unsigned Events()
Get the events.
void actualDeliver(DisconnectRequest *req)
disconnect
virtual X509 * GetPeerCertificate()
Get the peer certificate.
virtual void Deliver(ConnectAccept *req)
accept
virtual TLS_CipherSuite GetCipherSuite()
Get the cipher suite.
virtual void Deliver(StreamControl *option)
Control stream.
virtual void Deliver(StartTLS *req)
Start SSL/TLS on stream.
void actualDeliver(ConnectAccept *req)
accept
virtual endpoint_t GetEndpoint(bool inheriting)
Get the endpoint ID.
virtual void Deliver(External *ext)
Set external.
virtual void Deliver(LengthFnxRequest *)
Set length function.
virtual void Deliver(ReadRequest *req)
Read request.
virtual void Die()
Make this provider go away.
virtual void Deliver(DisconnectRequest *req)
disconnect
virtual void Deliver(DataRequest *req)
send data
virtual void Deliver(ListenRequest *req)
listen
virtual void Die()
Make this go away.
virtual void Deliver(::Poll::pollmsg *msg)
Deliver events from Poll provider.
virtual SocketPoll * Clone()
Make one like this.
virtual void Deliver(External *ext)
Set external.
virtual void Deliver(ReadRequest *req)
Read request.
virtual void Deliver(ConnectRequest *req)
connect
virtual void Deliver(StreamControl *option)
Control stream.
virtual void Deliver(time_t *msg)
Handle timer event.
virtual void Deliver(ConnectAccept *req)
accept
virtual void Deliver(DataRequest *req)
send data
virtual void Deliver(StartTLS *req)
Start SSL/TLS on stream.
virtual void Deliver(DisconnectRequest *req)
disconnect
virtual void Deliver(ConnectIndication *data)=0
Connection indication.
Class used to wrap each event object type for a given receiver.
void Init(C *rcvr)
Set the target.
Template class for protecting an object.
void msgDeliver(M *msg)
template function for delivering message of given type to receiver
Interface between a user of a stream and the provider of a stream.
@ StreamControlTOS
Keep alive flag.
@ StreamControlKeepAlive
No delay flag.
Carries the events on the appropriate FD, or that the end point should terminate.
const struct sockaddr * saddr
Pointer to new provider.
Provider * newprovider
Pointer to listening provider.
socklen_t salen
Caller's Source address.
socklen_t lalen
Local address.
const struct sockaddr * laddr
Length of Source address.
unsigned dscp
Length of Source address.
socklen_t dalen
Destination address.
const struct sockaddr * saddr
Length of destination address.
socklen_t salen
Optional Source address.
ssize_t len
Address of data.
Information for sending data.
size_t len
Pointer to data to be transferred.
Push an external endpoint into the provider.
bool listen
The network endpoint from some external source.
socklen_t lalen
Listen address.
int backlog
Length of listen address.
bool fill
Length of data read.
size_t len
Address of data.
ssize_t len
Buffer to be released.
Initiate SSL/TLS on the stream.
const char * hostname
The context for SSL.
bool client
Hostname to check (can be NULL)
int value
Option whose value is to be set.