19#include <openssl/err.h>
24#include "../include/Syncmsg.h"
26#include <isode/messages/base.h>
27#include <isode/base/crypto.h>
28#include <isode/compat/Common.h>
30#include <boost/optional.hpp>
35#define MAXSOCKADDRLEN 1024
40 enum class Version { VERS_1, VERS_2 } version;
41 enum class State { BEGIN, HEADER, HEADER_BODY, HEADER_DONE } state;
43 ProxyBuf() : version(Version::VERS_2), state(State::BEGIN), header_read(0), header_len(0), remaining(0), local(
false)
45 memset(&raddr, 0,
sizeof raddr);
53 sockaddr_storage raddr;
56 static inline bool starts_with(
const std::string& str,
const std::string& prefix)
58 return str.size() >= prefix.size() && str.substr(0, prefix.size()) == prefix;
94 struct sockaddr_storage _caddr;
96 struct sockaddr_storage _laddr;
99 const char * _hostname;
116 boost::optional<ProxyBuf> proxybuf_;
119 inline bool checkUser () {
121 MSG_IOevent_MissingUser_LOG ();
128 inline bool wouldBlock () {
129 return ( errno == EWOULDBLOCK || errno == EAGAIN );
133 inline void waitEvent (
unsigned events);
137 inline void handleProxyError();
141 inline bool handleReadError (ssize_t nbytes);
145 inline bool doProxy ();
149 inline bool doRead ();
153 inline bool doWrite ();
156 inline void doAccept ();
162 inline int doTLSread();
166 inline int doTLSwrite();
170 inline int doTLShandshake();
174 inline int doTLSshutdown();
177 inline bool setTrafficClass (
180 unsigned traffic_class);
190 _state (State_noconnect),
214 if ( _poller != 0 ) {
220 int err = SSL_get_error(_ssl, 0);
221 if (err != SSL_ERROR_NONE) {
223 LOG_DEBUG ((
"SocketPoll::tidy() - SSL error (%d)", err));
229 _fd = INVALID_ENDPOINT;
232 }
else if (
_fd != INVALID_ENDPOINT ) {
233 if ( _poller != 0 ) {
242 shutdown (
_fd, SHUT_WR);
245 _fd = INVALID_ENDPOINT;
254 _state = State_noconnect;
264 if ( SetHandleInformation ((HANDLE)
_fd,
266 HANDLE_FLAG_INHERIT) == 0 ) {
267 MSG_IOevent_Inherit_LOG();
270#elif defined (FD_CLOEXEC)
271 int flags = fcntl (
_fd, F_GETFD, 0);
274 flags &= ~FD_CLOEXEC;
275 if ( fcntl (
_fd, F_SETFD, flags) != 0 ) {
276 MSG_IOevent_Inherit_LOG ();
292 MSGstruct *msp)
override {
294 if (
_fd == INVALID_ENDPOINT ) {
295 MSG_IOevent_NotConnected_SET (msp);
296 return MSG_IOevent_NotConnected;
299#ifdef GETSOCKNAME_NEEDS_INTP
305 if ( getsockname (
_fd, laddr, &lalen) != 0 ) {
307 MSG_IOevent_IOerror_SET (msp,
"getsockname");
308 return MSG_IOevent_IOerror;
312 *lalenp = convert2ipv4 (laddr, lalen);
319 MSGstruct *msp)
override {
321 if (
_fd == INVALID_ENDPOINT ) {
322 MSG_IOevent_NotConnected_SET (msp);
323 return MSG_IOevent_NotConnected;
326#ifdef GETPEERNAME_NEEDS_INTP
332 if ( getpeername (
_fd, laddr, &lalen) != 0 ) {
334 MSG_IOevent_IOerror_SET (msp,
"getpeername");
335 return MSG_IOevent_IOerror;
339 *lalenp = convert2ipv4 (laddr, lalen);
345 if ( _state != State_tls || _ssl == 0 )
346 return TLS_NULL_WITH_NULL_NULL;
348 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
349 return SSLTLS::cipher_id(cipher);
354 if ( _state != State_tls || _ssl == 0 )
357 return SSL_get_peer_certificate(_ssl);
548inline void Stream::SocketPoll::waitEvent (
unsigned events)
550 StatusIndication statusind (
this);
552 if (
_fd == INVALID_ENDPOINT )
555 if ( _poller == 0 ) {
558 if ( _poller == 0 ) {
559 MSG_IOevent_NoPollProvider_SET (&statusind.msg);
568 MSG_IOevent_PollRegister_SET (&statusind.msg, rc);
583bool Stream::SocketPoll::doWrite ()
585 ssize_t remain = (ssize_t)_wlen - (_wptr - _wbuf);
586 ssize_t tosend = remain;
589 LOG_DEBUG ((
"SocketPoll::doWrite() - send %ld", (
long)tosend));
592 nbytes = send (_fd, _wptr, tosend, 0);
595 StatusIndication statusind (
this);
599 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
611 if (errno == ENOBUFS) {
614 LOG_DEBUG ((
"SocketPoll::doWrite() - retry send with %d", tosend));
617 if ((tosend == 0) || (errno != ENOBUFS)) {
619 MSG_IOevent_IOerror_SET (&statusind.msg,
"send");
625 MSG_IOevent_IOerror_SET (&statusind.msg,
"send");
630 GetUser()->Deliver (&statusind);
647 release.len = _wptr - _wbuf;
652 GetUser()->Deliver (&release);
662void Stream::SocketPoll::handleProxyError() {
664 MSG_IOevent_IOerror_SET (&statusind.msg,
"PROXY");
665 GetUser()->Deliver (&statusind);
669bool Stream::SocketPoll::handleReadError (ssize_t nbytes)
671 StatusIndication statusind (
this);
675 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
685 MSG_IOevent_IOerror_SET (&statusind.msg,
"recv");
688 GetUser()->Deliver (&statusind);
695bool Stream::SocketPoll::doProxy ()
698 proxybuf_ = ProxyBuf();
701 LOG_DEBUG ((
"doProxy: state=%d read=%d, len=%d remain=%d",
702 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
703 proxybuf_->header_len, proxybuf_->remaining));
705 ProxyBuf& pb = *proxybuf_;
710 case ProxyBuf::State::BEGIN: {
711 len = recv (_fd, &b, 1, 0);
715 pb.version = ProxyBuf::Version::VERS_1;
718 pb.state = ProxyBuf::State::HEADER;
721 pb.version = ProxyBuf::Version::VERS_2;
724 pb.state = ProxyBuf::State::HEADER;
726 LOG_DEBUG ((
"doProxy: Read V2 BEGIN state=%d read=%d, len=%d remain=%d",
727 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
728 proxybuf_->header_len, proxybuf_->remaining));
731 MSG_IOevent_ProxyError_LOG(b, _fd,
"Unknown PROXY version");
736 return handleReadError(len);
740 case ProxyBuf::State::HEADER:
741 switch (pb.version) {
742 case ProxyBuf::Version::VERS_1:
743 len = recv (_fd, &b, 1, 0);
751 if (pb.buf[pb.buf.length() - 1] !=
'\r') {
752 MSG_IOevent_ProxyError_LOG(1, _fd,
"read CR but previous character was not newline");
758 pb.state = ProxyBuf::State::HEADER_DONE;
767 MSG_IOevent_ProxyError_LOG(1, _fd,
"read a non-ascii character");
772 return handleReadError(len);
774 case ProxyBuf::Version::VERS_2: {
775 ssize_t to_read = 16 - pb.header_read;
776 len = recv (_fd, &(*pb.buf.begin())+pb.header_read, to_read, 0);
778 return handleReadError(len);
781 pb.header_read += len;
782 if (len == to_read) {
783 pb.state = ProxyBuf::State::HEADER_BODY;
784 auto ph =
reinterpret_cast<proxy_hdr_v2*
>(&pb.buf[0]);
785 if (0 != std::memcmp(ph->sig, v2sig, 12) || 0x20 != (ph->ver_cmd & 0x20)) {
786 MSG_IOevent_ProxyError_LOG(2, _fd,
"signature did not match");
790 pb.remaining = ntohs(ph->len);
791 pb.header_len = 16 + pb.remaining;
792 if (pb.remaining > 520) {
794 MSG_IOevent_ProxyError_LOG(2, _fd,
"length is much too big");
798 pb.buf.resize(pb.header_len);
799 LOG_DEBUG ((
"doProxy: Read V2 header state=%d read=%d, len=%d remain=%d",
800 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
801 proxybuf_->header_len, proxybuf_->remaining));
804 LOG_DEBUG ((
"doProxy: Read V2 partial header state=%d read=%d, len=%d remain=%d",
805 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
806 proxybuf_->header_len, proxybuf_->remaining));
811 case ProxyBuf::State::HEADER_BODY:
812 len = recv (_fd, &(*pb.buf.begin()) + pb.header_read, pb.remaining, 0);
814 return handleReadError(len);
817 pb.header_read += len;
818 if (0 == pb.remaining) {
819 pb.state = ProxyBuf::State::HEADER_DONE;
820 LOG_DEBUG ((
"doProxy: Read V2 body state=%d read=%d, len=%d remain=%d",
821 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
822 proxybuf_->header_len, proxybuf_->remaining));
824 LOG_DEBUG ((
"doProxy: Read V2 partial body state=%d read=%d, len=%d remain=%d",
825 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
826 proxybuf_->header_len, proxybuf_->remaining));
830 case ProxyBuf::State::HEADER_DONE: {
831 if (pb.version == ProxyBuf::Version::VERS_1) {
833 pb.buf = pb.buf.substr(0, pb.buf.length()-2);
834 if (!starts_with(pb.buf,
"PROXY ")) {
835 MSG_IOevent_ProxyError_LOG(1, _fd,
"header did not begin with PROXY");
839 pb.buf = pb.buf.substr(6);
840 if (starts_with(pb.buf,
"LOCAL ")) {
846 }
else if (starts_with(pb.buf,
"TCP4 ")) {
848 if (!read_proxy_ipv4(pb.buf.substr(5), pa)) {
849 MSG_IOevent_ProxyError_LOG(1, _fd,
"failed to decode TCP4 header");
853 auto raddr =
reinterpret_cast<sockaddr_in*
>(&pb.raddr);
854 raddr->sin_family = AF_INET;
855 *
reinterpret_cast<in_addr_t*
>(&raddr->sin_addr) = pa.src_addr;
856 raddr->sin_port = htons(pa.src_port);
858 }
else if (starts_with(pb.buf,
"TCP6 ")) {
860 if (!read_proxy_ipv6(pb.buf.substr(5), pa)) {
861 MSG_IOevent_ProxyError_LOG(1, _fd,
"failed to decode TCP6 header");
865 auto raddr =
reinterpret_cast<sockaddr_in6*
>(&pb.raddr);
866 raddr->sin6_family = AF_INET6;
867 std::memcpy(&raddr->sin6_addr, &pa.src_addr,
sizeof(raddr->sin6_addr));
868 raddr->sin6_port = htons(pa.src_port);
871 MSG_IOevent_ProxyError_LOG(1, _fd,
"second word was not LOCAL, TCP4, or TCP6");
875 }
else if (pb.version == ProxyBuf::Version::VERS_2) {
876 auto ph =
reinterpret_cast<proxy_hdr_v2*
>(&pb.buf[0]);
877 std::uint8_t cmd = ph->ver_cmd & 0x0f;
884 MSG_IOevent_ProxyError_LOG(2, _fd,
"command was not LOCAL or PROXY");
889 if ((ph->fam & 0x0f) != 0x1) {
891 MSG_IOevent_ProxyError_LOG(2, _fd,
"non-STREAM transport protocol");
896 switch (ph->fam & 0xf0) {
898 if (pb.header_len < 16 +
sizeof(ipv4_addr)) {
899 MSG_IOevent_ProxyError_LOG(2, _fd,
"message length too small to hold TCP4 information");
903 auto pa =
reinterpret_cast<const ipv4_addr*
>(pb.buf.c_str()+16);
904 auto raddr =
reinterpret_cast<sockaddr_in*
>(&pb.raddr);
905 raddr->sin_family = AF_INET;
906 *
reinterpret_cast<in_addr_t*
>(&raddr->sin_addr) = pa->src_addr;
907 raddr->sin_port = pa->src_port;
911 if (pb.header_len < 16 +
sizeof(ipv6_addr)) {
912 MSG_IOevent_ProxyError_LOG(2, _fd,
"message length too small to hold TCP6 information");
916 auto pa =
reinterpret_cast<const ipv6_addr*
>(pb.buf.c_str()+16);
917 auto raddr =
reinterpret_cast<sockaddr_in6*
>(&pb.raddr);
918 raddr->sin6_family = AF_INET6;
919 std::memcpy(&raddr->sin6_addr, &pa->src_addr,
sizeof(raddr->sin6_addr));
920 raddr->sin6_port = pa->src_port;
925 MSG_IOevent_ProxyError_LOG(2, _fd,
"unknown family");
932 if (!pb.local && pb.raddr.ss_family == AF_UNSPEC) {
933 MSG_IOevent_ProxyError_LOG(-1, _fd,
"unable to determine remote address family");
936 _state = State_connected;
937 LOG_DEBUG ((
"doProxy: Read proxy state=%d read=%d, len=%d remain=%d",
938 static_cast<int>(proxybuf_->state), proxybuf_->header_read,
939 proxybuf_->header_len, proxybuf_->remaining));
945 ProxyIndication proxyind;
946 proxyind.local = pb.local;
947 proxyind.raddr =
reinterpret_cast<sockaddr *
>(&pb.raddr);
948 GetUser()->DeliverProxy (&proxyind);
957bool Stream::SocketPoll::doRead ()
959 ssize_t remain = (ssize_t)_rlen - (_rptr - _rbuf);
961 LOG_DEBUG ((
"doRead: _rlen=%d remain=%d", (
int)_rlen, (
int)remain));
963 ssize_t nbytes = recv (_fd, _rptr, remain, 0);
965 LOG_DEBUG ((
"doRead: recv -> %d", (
int)nbytes));
968 return handleReadError (nbytes);
972 if ( nbytes == remain )
978 LOG_DEBUG ((
"doRread: remain=%d _rfill=%d", (
int)remain, _rfill));
982 if ( !_rfill || remain == 0 ) {
983 DataIndication dataind;
986 dataind.len = _rptr - _rbuf;
991 GetUser()->Deliver (&dataind);
1000void Stream::SocketPoll::doAccept ()
1002 StatusIndication statusind (
this);
1003 char abuf[MAXSOCKADDRLEN];
1004#ifdef ACCEPT_NEEDS_INTP
1011 endpoint_t newfd = accept (_fd, (
struct sockaddr *)abuf, &alen);
1012 if (INVALID_ENDPOINT == newfd) {
1020 MSG_IOevent_AcceptError_SET (&statusind.msg);
1021 MSGappendsyserror (&statusind.msg);
1022 GetUser()->Deliver (&statusind);
1028 MSG_IOevent_AcceptError_SET (&statusind.msg);
1029 MSGappendsyserror (&statusind.msg);
1030 GetUser()->Deliver (&statusind);
1034 if ( _emfile > 100 ) _emfile = 100;
1036 _timer.Sendms (100*_emfile, dummy);
1052 MSG_IOevent_IOerror_SET (&statusind.msg,
"accept");
1053 GetUser()->Deliver (&statusind);
1063#if defined(EWOULDBLOCK)
1064# if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
1075 if ( SetHandleInformation(
1077 HANDLE_FLAG_INHERIT,
1079 MSG_IOevent_Inherit_LOG();
1081#elif defined (FD_CLOEXEC)
1082 (void) fcntl(newfd, F_SETFD, FD_CLOEXEC);
1085 bool do_setsockopt =
true;
1087 if ( fcntl(newfd, F_SETFL, O_NONBLOCK) != 0 ) {
1089 MSG_IOevent_IoctlError_SET(&statusind.msg);
1090 MSGappendsyserror(&statusind.msg);
1091 GetUser()->Deliver(&statusind);
1092 do_setsockopt =
false;
1094#elif defined(FIONBIO)
1096 if ( ioctl(newfd, FIONBIO, &onoff) != 0 ) {
1098 MSG_IOevent_IoctlError_SET(&statusind.msg);
1099 MSGappendsyserror(&statusind.msg);
1100 GetUser()->Deliver(&statusind);
1101 do_setsockopt =
false;
1104#error Cannot set socket into non-blocking more
1106 if (do_setsockopt) {
1115 setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
sizeof nodelay);
1123 setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE, (
char *)&keepalive,
sizeof keepalive);
1128 connind.listener =
this;
1131 newprov->
_fd = newfd;
1132 newprov->_state = State_accepting;
1134 memcpy(&newprov->_caddr, abuf, alen);
1135 newprov->_clen = alen;
1137 connind.
saddr =
reinterpret_cast<struct sockaddr *
>(&newprov->_caddr);
1138 connind.
salen = convert2ipv4(
reinterpret_cast<struct sockaddr *
>(&newprov->_caddr), alen);
1140#ifdef GETSOCKNAME_NEEDS_INTP
1145 llen =
sizeof newprov->_laddr;
1146 newprov->_llen =
sizeof newprov->_laddr;
1148 getsockname(newfd,
reinterpret_cast<struct sockaddr *
>(&newprov->_laddr), &llen);
1150 newprov->_llen = llen;
1152 connind.
laddr =
reinterpret_cast<struct sockaddr *
>(&newprov->_laddr);
1153 connind.
lalen = newprov->_llen;
1155 GetUser()->Deliver(&connind);
1163 waitEvent (::Poll::Event_In);
1167int Stream::SocketPoll::doTLSread ()
1169 int remain = (int)_rlen - (_rptr - _rbuf);
1171 LOG_DEBUG ((
"doTLSread: _rlen=%d remain=%d", (
int)_rlen, (
int)remain));
1173 int nbytes = SSL_read (_ssl, _rptr, remain);
1175 LOG_DEBUG ((
"doTLSread: SSL_read -> %d", nbytes));
1181 if ( nbytes == 0 ) {
1182 StatusIndication statusind (
this);
1184 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1186 GetUser()->Deliver (&statusind);
1188 _tlsstate = TLS_idle;
1195 if ( nbytes == remain )
1201 LOG_DEBUG ((
"doTLSread: remain=%d _rfill=%d", (
int)remain, _rfill));
1205 if ( !_rfill || remain == 0 ) {
1206 DataIndication dataind;
1208 dataind.buf = _rbuf;
1209 dataind.len = _rptr - _rbuf;
1214 _tlsstate = TLS_idle;
1216 GetUser()->Deliver (&dataind);
1222int Stream::SocketPoll::doTLSwrite ()
1224 int remain = (int)_wlen - (_wptr - _wbuf);
1225 LOG_DEBUG ((
"doTLSwrite: _wlen=%d remain=%d", (
int)_wlen, (
int)remain));
1227 int nbytes = SSL_write (_ssl, _wptr, remain);
1228 LOG_DEBUG ((
"doTLSwrite: SSL_write -> %d", nbytes));
1237 if ( remain == 0 ) {
1240 release.buf = _wbuf;
1241 release.len = _wptr - _wbuf;
1246 GetUser()->Deliver (&release);
1248 _tlsstate = TLS_idle;
1254int Stream::SocketPoll::doTLShandshake ()
1256 int rc = SSL_do_handshake (_ssl);
1257 LOG_DEBUG ((
"doTLShandshake: SSL_do_handshake -> %d", rc));
1262 StatusIndication statusind (
this);
1265 _tlsstate = TLS_idle;
1270 _tlsstate = TLS_idle;
1272 const char *version = SSL_get_version(_ssl);
1274 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
1275 TLS_CipherSuite cs = SSLTLS::cipher_id(cipher);
1276 int strength = SSL_CIPHER_get_bits(cipher, NULL);
1278 X509 *peer = SSL_get_peer_certificate(_ssl);
1280 bool closing =
true;
1285 if ( _choice == SSLTLS::tls_verify_require ) {
1286 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
1287 MSG_IOevent_SSLnocert_SET (&submsg);
1288 MSGappend (&statusind.msg, &submsg);
1291 MSG_IOevent_SSLOK_SET (&statusind.msg,
1292 version, cs, strength);
1297 }
else if ( _choice == SSLTLS::tls_verify_none ) {
1298 MSG_IOevent_SSLOK_SET (&statusind.msg,
1299 version, cs, strength);
1305 X509_NAME *subject_name = X509_get_subject_name(peer);
1307 long result = SSL_get_verify_result(_ssl);
1308 char *peername = X509_NAME_to_text (subject_name);
1313 MSG_IOevent_SSLverified_SET (&statusind.msg,
1314 version, cs, strength,
1318 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1319 MSG_IOevent_SSLnoissuercert_SET (&submsg);
1321 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1322 MSG_IOevent_SSLcertdecryptfailed_SET (&submsg);
1324 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1325 MSG_IOevent_SSLcertsignature_SET (&submsg);
1327 case X509_V_ERR_CERT_NOT_YET_VALID:
1328 MSG_IOevent_SSLcertnotyetvalid_SET (&submsg);
1330 case X509_V_ERR_CERT_HAS_EXPIRED:
1331 MSG_IOevent_SSLcertexpired_SET (&submsg);
1333 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1334 MSG_IOevent_SSLcertnotbefore_SET (&submsg);
1336 case X509_V_ERR_OUT_OF_MEM:
1337 MSG_Base_Nomem_SET (&submsg, 0);
1339 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1340 MSG_IOevent_SSLselfsigned_SET (&submsg);
1342 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1343 MSG_IOevent_SSLlocalissuer_SET (&submsg);
1345 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1346 MSG_IOevent_SSLleafsignature_SET (&submsg);
1348 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1349 MSG_IOevent_SSLchaintoolong_SET (&submsg);
1351 case X509_V_ERR_INVALID_CA:
1352 MSG_IOevent_SSLinvalidCA_SET (&submsg);
1354 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1355 MSG_IOevent_SSLpathlength_SET (&submsg);
1357 case X509_V_ERR_INVALID_PURPOSE:
1358 MSG_IOevent_SSLinvalidpurpose_SET (&submsg);
1360 case X509_V_ERR_CERT_UNTRUSTED:
1361 MSG_IOevent_SSLuntrusted_SET (&submsg);
1363 case X509_V_ERR_CERT_REJECTED:
1364 MSG_IOevent_SSLrejected_SET (&submsg);
1366 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
1367 MSG_IOevent_SSLsubjectissuer_SET (&submsg);
1369 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
1370 MSG_IOevent_SSLserialmismatch_SET (&submsg);
1372 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
1373 MSG_IOevent_SSLkeyusage_SET (&submsg);
1376 MSG_IOevent_SSLunknown_SET (&submsg, result);
1381 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
1382 MSGappend (&statusind.msg, &submsg);
1385 if (x509_acceptable_name(subject_name) != OK) {
1387 MSG_IOevent_SSLnul_in_subject_LOG(peername);
1390 if ( peername != 0 )
1395 if (!closing && _hostname &&
1396 SSLTLS::CheckHostname (peer, _hostname, &statusind.msg) != OK ) {
1403 _tlsstate = TLS_idle;
1405 GetUser()->Deliver (&statusind);
1413int Stream::SocketPoll::doTLSshutdown ()
1415 int rc = SSL_shutdown (_ssl);
1416 LOG_DEBUG ((
"SocketPoll::doTLSshutdown() -> %d", rc));
1420 LOG_DEBUG ((
"SocketPoll::doTLSshutdown() - shutdown in progress"));
1422 int err = SSL_get_error(_ssl, rc);
1423 LOG_DEBUG ((
"SocketPoll::doTLSshutdown() - SSL error (%d)", err));
1430 StatusIndication statusind (
this);
1431 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1432 GetUser()->Deliver (&statusind);
1435 _tlsstate = TLS_idle;
1441void Stream::SocketPoll::doTLS ()
1443 LOG_DEBUG ((
"SocketPoll::doTLS()"));
1451 switch ( _tlsstate ) {
1454 _tlsstate = TLS_write;
1457 }
else if ( _rlen != 0 ) {
1470 rc = doTLShandshake();
1474 rc = doTLSshutdown();
1478 if ( rc > 0 )
continue;
1480 StatusIndication statusind (
this);
1482 switch (SSL_get_error(_ssl, rc)) {
1483 case SSL_ERROR_NONE:
1487 case SSL_ERROR_ZERO_RETURN:
1489 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1492 case SSL_ERROR_WANT_READ:
1493 waitEvent (::Poll::Event_In);
1496 case SSL_ERROR_WANT_WRITE:
1497 waitEvent (::Poll::Event_Out);
1500 case SSL_ERROR_SYSCALL:
1502 if (ERR_get_error()==0) {
1505 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1507 MSG_IOevent_IOerror_SET (&statusind.msg,
"SSL");
1510 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_ERROR_SYSCALL");
1515 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_ERROR_SSL");
1518 case SSL_ERROR_WANT_CONNECT:
1519 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_WANT_CONNECT");
1522 case SSL_ERROR_WANT_ACCEPT:
1523 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,
"SSL_WANT_ACCEPT");
1529 snprintf (buf,
sizeof buf,
"err=%d", SSL_get_error(_ssl, rc));
1530 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, buf);
1535 GetUser()->Deliver (&statusind);
1544 waitEvent (::Poll::Event_In);
1549 if ( checkUser() )
return;
1553 LOG_DEBUG ((
"SocketPoll::actualDeliver (pollmsg = %x) state=%d",
1554 msg->events, _state));
1559 if ( (msg->events & ::Poll::Event_Terminate) ) {
1565 _fd = INVALID_ENDPOINT;
1569 MSG_IOevent_Terminating_SET (&statusind.msg);
1570 GetUser()->Deliver (&statusind);
1576 (::Poll::Event_Err | ::Poll::Event_Hup | ::Poll::Event_Nval) ) {
1583#ifdef GETSOCKOPT_NEEDS_INTP
1591 int rc = getsockopt (_fd, SOL_SOCKET, SO_ERROR, (
char *)&eno, &olen);
1593 const char *argv[1];
1596 MSGsetv (&statusind.msg, MSG_IOevent_IOerror, 1, argv);
1601 MSGID_BUILD(MSGLEVEL_ERROR, MSGID_SYSFAC, eno),
1603 MSGappend (&statusind.msg, &sockerr);
1605 MSGappendsyserror (&statusind.msg);
1608 GetUser()->Deliver (&statusind);
1616 _uevents &= ~msg->events;
1618 if ( msg->events & ::Poll::Event_In ) {
1625 case State_need_proxy:
1627 waitEvent (::Poll::Event_In);
1629 case State_connected:
1630 LOG_DEBUG ((
"Read stuff: _rlen = %d", (
int)_rlen));
1634 waitEvent (::Poll::Event_In);
1638 case State_listening:
1647 if ( msg->events & ::Poll::Event_Out ) {
1654 case State_need_proxy:
1656 LOG_DEBUG ((
"Need proxy state seen when writing"));
1658 case State_connected:
1662 waitEvent (::Poll::Event_Out);
1666 case State_connecting:
1667 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
1668 MSG_IOevent_Connected_SET (&statusind.msg);
1669 GetUser()->Deliver (&statusind);
1677 if ( (_uevents & ~_pevents) && _poller )
1678 _poller->Control (
this);
1683 if ( checkUser() )
return;
1687 LOG_DEBUG ((
"SocketPoll::actualDeliver (External)"));
1689 if ( _state != State_noconnect ) {
1690 MSG_IOevent_NotConnected_SET (&statusind.msg);
1691 GetUser()->Deliver (&statusind);
1698 _state = State_listening;
1700 waitEvent (::Poll::Event_In);
1703 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
1709 if ( checkUser() )
return;
1713 LOG_DEBUG ((
"SocketPoll::actualDeliver (ConnectRequest)"));
1715 if ( _state != State_noconnect ) {
1716 MSG_IOevent_NotConnected_SET (&statusind.msg);
1717 GetUser()->Deliver (&statusind);
1722#if defined(AF_INET6) && defined(PF_INET6)
1723 struct sockaddr_in6 ipv6addr;
1726 switch ( req->daddr->sa_family ) {
1727#if defined(AF_UNIX) && defined(PF_UNIX)
1737#if defined(AF_INET6) && defined(PF_INET6)
1740 if ( req->
dscp != 0 ) {
1742 ipv6addr = *
reinterpret_cast<const struct sockaddr_in6 *
>
1747 ipv6addr.sin6_flowinfo = htonl (req->
dscp << 22);
1749 req->daddr =
reinterpret_cast<struct sockaddr *
>(&ipv6addr);
1755 MSG_IOevent_AddrType_SET (&statusind.msg, req->daddr->sa_family);
1756 GetUser()->Deliver (&statusind);
1760 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1762 if ( fd == INVALID_ENDPOINT ) {
1763 MSG_IOevent_IOerror_SET (&statusind.msg,
"socket");
1764 GetUser()->Deliver (&statusind);
1770 if ( SetHandleInformation ((HANDLE)fd,
1771 HANDLE_FLAG_INHERIT,
1773 MSG_IOevent_Inherit_LOG ();
1775#elif defined (FD_CLOEXEC)
1776 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1780 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1781 MSG_IOevent_IOerror_SET (&statusind.msg,
"fcntl");
1782 GetUser()->Deliver (&statusind);
1786#elif defined (FIONBIO)
1788 if ( ioctl (fd, FIONBIO, &onoff) != 0 ) {
1789 MSG_IOevent_IOerror_SET (&statusind.msg,
"ioctl");
1790 GetUser()->Deliver (&statusind);
1795# error Cannot set socket into non-blocking more
1807 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nodelay,
sizeof nodelay);
1816 setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,
1817 (
char *)&keepalive,
sizeof keepalive);
1820 if ( req->
dscp != 0 && !setTrafficClass (fd, family, req->
dscp) ) {
1821 MSG_IOevent_IOerror_SET (&statusind.msg,
"traffic class");
1822 GetUser()->Deliver (&statusind);
1829 MSG_IOevent_IOerror_SET (&statusind.msg,
"bind calling address");
1830 GetUser()->Deliver (&statusind);
1835 if ( connect (fd, req->daddr, req->
dalen) != 0 ) {
1837 if ( errno == EINPROGRESS || wouldBlock () ) {
1840 _state = State_connecting;
1843 waitEvent (::Poll::Event_Out);
1846 MSG_IOevent_IOerror_SET (&statusind.msg,
"connect");
1847 GetUser()->Deliver (&statusind);
1855 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
1857 MSG_IOevent_Connected_SET (&statusind.msg);
1858 GetUser()->Deliver (&statusind);
1862bool Stream::SocketPoll::setTrafficClass (
1865 unsigned traffic_class)
1867 if ( family == PF_INET ) {
1870 int tosbyte = traffic_class << 2;
1873# define TOSLEVEL SOL_IP
1875# define TOSLEVEL IPPROTO_IP
1877 return setsockopt (fd, TOSLEVEL, IP_TOS,
1878 (
char *)&tosbyte,
sizeof tosbyte) == 0;
1890 if ( checkUser() )
return;
1894 LOG_DEBUG ((
"SocketPoll::actualDeliver (ListenRequest)"));
1896 if ( _state != State_noconnect ) {
1897 MSG_IOevent_NotConnected_SET (&statusind.msg);
1899 GetUser()->Deliver (&statusind);
1906 switch ( req->laddr->sa_family ) {
1917#if defined(AF_INET6) && defined(PF_INET6)
1924 MSG_IOevent_AddrType_SET (&statusind.msg, req->laddr->sa_family);
1925 GetUser()->Deliver (&statusind);
1929 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1931 if ( fd == INVALID_ENDPOINT ) {
1932 MSG_IOevent_IOerror_SET (&statusind.msg,
"socket");
1933 GetUser()->Deliver (&statusind);
1937#if defined(PF_INET6) && defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
1938 if ( family == PF_INET6 ) {
1941 if ( setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY,
1942 (
char *)&v6only,
sizeof v6only) != 0 ) {
1943 MSG_IOevent_IOerror_SET (&statusind.msg,
"setsockopt");
1944 GetUser()->Deliver (&statusind);
1951#if !defined(IC_WIN32) && defined(SO_REUSEADDR)
1954 if ( setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
1955 (
char *)&onoff,
sizeof onoff) != 0 ) {
1956 MSG_IOevent_IOerror_SET (&statusind.msg,
"setsockopt");
1957 GetUser()->Deliver (&statusind);
1963 if ( bind (fd, req->laddr, req->
lalen ) != 0 ) {
1964 MSG_IOevent_IOerror_SET (&statusind.msg,
"bind");
1965 GetUser()->Deliver (&statusind);
1972 if ( SetHandleInformation ((HANDLE)fd,
1973 HANDLE_FLAG_INHERIT,
1975 MSG_IOevent_Inherit_LOG ();
1977#elif defined (FD_CLOEXEC)
1978 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1982 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1983 MSG_IOevent_IOerror_SET (&statusind.msg,
"fcntl");
1984 GetUser()->Deliver (&statusind);
1988#elif defined (FIONBIO)
1990 if ( ioctl (fd, FIONBIO, &con) != 0 ) {
1991 MSG_IOevent_IOerror_SET (&statusind.msg,
"ioctl");
1992 GetUser()->Deliver (&statusind);
1997# error Cannot set socket into non-blocking more
2000 if ( listen (fd, req->
backlog ? req->
backlog : SOMAXCONN) != 0 ) {
2001 MSG_IOevent_IOerror_SET(&statusind.msg,
"listen");
2002 GetUser()->Deliver (&statusind);
2009 _state = State_listening;
2012 waitEvent (::Poll::Event_In);
2017 if ( checkUser() )
return;
2021 LOG_DEBUG ((
"SocketPoll::actualDeliver (ConnectAccept)"));
2023 if ( _fd == INVALID_ENDPOINT || _state != State_accepting ) {
2024 MSG_IOevent_NotConnected_SET (&statusind.msg);
2026 GetUser()->Deliver (&statusind);
2032 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
2037 if ( checkUser() )
return;
2039 StatusIndication statusind (
this);
2041 LOG_DEBUG ((
"SocketPoll::actualDeliver (DisconnectRequest)"));
2044 case State_need_proxy:
2045 case State_connected:
2046 case State_accepting:
2048 if ( _fd != INVALID_ENDPOINT )
2053 MSG_IOevent_NotConnected_SET (&statusind.msg);
2054 GetUser()->Deliver (&statusind);
2058 if ( _state == State_tls ) {
2059 _tlsstate = TLS_close;
2066 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
2067 GetUser()->Deliver (&statusind);
2075 if ( checkUser() )
return;
2079 LOG_DEBUG ((
"SocketPoll::actualDeliver (DataRequest) state=%d _wlen=%ld",
2080 _state, (
long)_wlen));
2083 case State_need_proxy:
2084 case State_connected:
2086 if ( _fd != INVALID_ENDPOINT )
2091 MSG_IOevent_NotConnected_SET (&statusind.msg);
2092 GetUser()->Deliver (&statusind);
2097 if ( req->buf == 0 || req->
len == 0 ) {
2098 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
2103 GetUser()->Deliver (&statusind);
2111 release.buf = req->buf;
2114 GetUser()->Deliver (&release);
2116 MSG_IOevent_DupWrite_SET (&statusind.msg);
2118 GetUser()->Deliver (&statusind);
2123 _wbuf = _wptr = req->buf;
2126 if ( _state == State_connected || _state == State_need_proxy ) {
2127 if (_state == State_need_proxy) {
2128 LOG_DEBUG ((
"Need proxy state seen when writing"));
2130 if ( !doWrite () ) {
2132 waitEvent (::Poll::Event_Out);
2142 if ( checkUser() )
return;
2147 LOG_DEBUG ((
"SocketPoll::actualDeliver (ReadRequest)"));
2150 case State_need_proxy:
2151 case State_connected:
2153 if ( _fd != INVALID_ENDPOINT )
2158 MSG_IOevent_NotConnected_SET (&statusind.msg);
2159 GetUser()->Deliver (&statusind);
2163 if ( req->buf == 0 || req->
len == 0 ) {
2164 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
2169 GetUser()->Deliver (&statusind);
2175 dataind.buf = req->buf;
2178 GetUser()->Deliver (&dataind);
2180 MSG_IOevent_DupRead_SET (&statusind.msg);
2182 GetUser()->Deliver (&statusind);
2187 _rbuf = _rptr = req->buf;
2191 LOG_DEBUG ((
"ReadRequest: _rbuf=%p _rlen=%d _rfill=%d",
2192 _rbuf, (
int)_rlen, _rfill));
2194 if ( _state == State_connected || _state == State_need_proxy ) {
2200 && ((_state == State_connected && doRead () )
2201 || (_state == State_need_proxy && doProxy() )) )
2205 waitEvent (::Poll::Event_In);
2214 if ( checkUser() )
return;
2216 LOG_DEBUG ((
"SocketPoll::actualDeliver (StartTLS)"));
2222 MSG_IOevent_SSLalready_SET (&statusind.msg);
2223 GetUser()->Deliver (&statusind);
2226 case State_connected:
2227 if ( _fd != INVALID_ENDPOINT )
2232 MSG_IOevent_NotConnected_SET (&statusind.msg);
2233 GetUser()->Deliver (&statusind);
2240 SSLTLS::OpenSSLContext *sslctx =
2241 dynamic_cast<SSLTLS::OpenSSLContext *
>(req->context);
2243 _ssl = sslctx ? sslctx->GetSSL(_choice) : NULL;
2245 MSG_IOevent_SSLerror_SET (&statusind.msg,
"SSL_new",
"this returned NULL. No ID configured?");
2246 GetUser()->Deliver (&statusind);
2251 int err = SSL_get_error(_ssl, 0);
2252 if (err != SSL_ERROR_NONE) {
2254 LOG_DEBUG ((
"SocketPoll::actualDeliver(StartTLS) - SSL error code %d", err));
2258 BIO *bio = BIO_new_socket (_fd, TRUE);
2260 SSL_set_bio(_ssl, bio, bio);
2263 SSL_set_connect_state (_ssl);
2265 SSL_set_accept_state (_ssl);
2268 _tlsstate = TLS_handshake;
2275 if ( checkUser() )
return;
2277 LOG_DEBUG ((
"SocketPoll::actualDeliver (StreamControl)"));
2281 if ( _fd == INVALID_ENDPOINT ) {
2282 MSG_IOevent_NotConnected_SET (&statusind.msg);
2283 GetUser()->Deliver (&statusind);
2290 switch ( option->option ) {
2291#if defined(TCP_NODELAY)
2292 case StreamControlNoDelay:
2293 level = IPPROTO_TCP;
2300 name = SO_KEEPALIVE;
2315 MSG_IOevent_UnknownStreamOpt_SET (&statusind.msg, option->option);
2316 GetUser()->Deliver (&statusind);
2320 int rc = setsockopt (_fd, level, name, (
char *)&option->
value,
sizeof option->
value);
2322 MSG_IOevent_IOerror_SET (&statusind.msg,
"setsockopt");
2323 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.
TLS_CipherSuite GetCipherSuite() override
Get the cipher suite.
virtual void Deliver(time_t *msg)
Handle timer event.
void Deliver(StartTLS *req) override
Start SSL/TLS on stream.
virtual SocketPoll * Clone()=0
Make another provider like this one.
void Deliver(DataRequest *req) override
send data
void tidy()
Tidy up - close connections etc.
int GetPeerAddress(struct sockaddr *laddr, socklen_t *lalenp, MSGstruct *msp) override
Get the peer address.
void Die() override
Make this provider go away.
void actualDeliver(time_t *msg)
Handle timer event.
void actualDeliver(DisconnectRequest *req)
disconnect
void Deliver(ListenRequest *req) override
listen
void Deliver(ConnectAccept *req) override
accept
void Deliver(StreamControl *option) override
Control stream.
int GetLocalAddress(struct sockaddr *laddr, socklen_t *lalenp, MSGstruct *msp) override
Get the local address.
void Deliver(DisconnectRequest *req) override
disconnect
void Deliver(LengthFnxRequest *) override
Set length function.
void actualDeliver(ConnectAccept *req)
accept
void Deliver(ConnectRequest *req) override
connect
X509 * GetPeerCertificate() override
Get the peer certificate.
void Deliver(ReadRequest *req) override
Read request.
void Deliver(::Poll::pollmsg *msg) override
Deliver events to Poll provider.
void Deliver(External *ext) override
Set external.
unsigned Events() override
Get the events.
endpoint_t GetEndpoint(bool inheriting) override
Get the endpoint ID.
void Deliver(ReadRequest *req) override
Read request.
void Deliver(time_t *msg) override
Handle timer event.
void Deliver(StartTLS *req) override
Start SSL/TLS on stream.
void Deliver(DisconnectRequest *req) override
disconnect
void Deliver(::Poll::pollmsg *msg) override
Deliver events from Poll provider.
SocketPoll * Clone() override
Make one like this.
void Deliver(StreamControl *option) override
Control stream.
void Die() override
Make this go away.
void Deliver(DataRequest *req) override
send data
void Deliver(ConnectAccept *req) override
accept
void Deliver(ConnectRequest *req) override
connect
void Deliver(ListenRequest *req) override
listen
void Deliver(External *ext) override
Set external.
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.