stream_socket_poll.C
1// -*- C++ -*-
2
3// Copyright (c) 2005-2010, Isode Limited, London, England.
4// All rights reserved.
5//
6// Acquisition and use of this software and related materials for any
7// purpose requires a written licence agreement from Isode Limited,
8// or a written licence from an organisation licenced by Isode Limited
9// to grant such a licence.
10
11//
12//
13// stream_socket_poll.C
14//
15// Stream provider using sockets and poll.
16//
17// @VERSION@
18
19#include <openssl/err.h>
20
21#include "Event_p.h"
22#include "Proxy.h"
23
24#include "../include/Syncmsg.h"
25
26#include <isode/messages/base.h>
27#include <isode/base/crypto.h>
28#include <isode/compat/Common.h>
29
30#include <boost/optional.hpp>
31
32// Should be set to the size of the longest sockaddr
33// There is no easy and portable way to define this.
34// The size here is probably generous.
35#define MAXSOCKADDRLEN 1024
36
37namespace Stream {
38
39 struct ProxyBuf {
40 enum class Version { VERS_1, VERS_2 } version;
41 enum class State { BEGIN, HEADER, HEADER_BODY, HEADER_DONE } state;
42
43 ProxyBuf() : version(Version::VERS_2), state(State::BEGIN), header_read(0), header_len(0), remaining(0), local(false)
44 {
45 memset(&raddr, 0, sizeof raddr);
46 }
47
48 uint16_t header_read;
49 uint16_t header_len;
50 uint16_t remaining;
51 std::string buf;
52 bool local;
53 sockaddr_storage raddr;
54 };
55
56 static inline bool starts_with(const std::string& str, const std::string& prefix)
57 {
58 return str.size() >= prefix.size() && str.substr(0, prefix.size()) == prefix;
59 }
60
61
63 // This is the core interface which we wrap to get the thread
64 // synchronization. In a non-thread environment, this could be
65 // used directly, which is more efficient.
66
67 class SocketPoll : public Provider, public ::Poll::User {
68 private:
69 ::Poll::Provider *_poller;
70 enum State {
71 State_noconnect,
72 State_listening,
73 State_connecting,
74 State_accepting,
75 State_need_proxy,
76 State_connected,
77 State_tls
78 } _state;
79
80 // Reader stuff
81 char * _rbuf;
82 char * _rptr;
83 size_t _rlen;
84 bool _rfill;
85 bool _rfull;
86
87 // Writer stuff
88 const char * _wbuf;
89 const char * _wptr;
90 size_t _wlen;
91
92 // Addresses for ConnectionIndication
93 socklen_t _clen;
94 struct sockaddr_storage _caddr;
95 socklen_t _llen;
96 struct sockaddr_storage _laddr;
97
98 SSL * _ssl;
99 const char * _hostname;
100
102
104 unsigned _emfile;
105
106 enum TLSstate {
107 TLS_idle,
108 TLS_handshake,
109 TLS_write,
110 TLS_close
111 } _tlsstate;
112
113 bool _noshut;
114
115 // PROXY buffer
116 boost::optional<ProxyBuf> proxybuf_;
117
119 inline bool checkUser () {
120 if ( GetUser() == 0 ) {
121 MSG_IOevent_MissingUser_LOG ();
122 return true;
123 }
124 return false;
125 }
126
128 inline bool wouldBlock () {
129 return ( errno == EWOULDBLOCK || errno == EAGAIN );
130 }
131
133 inline void waitEvent (unsigned events);
134
136 // Send status indication and tidy up
137 inline void handleProxyError();
138
140 // Common error handling code for doRead / doProxy
141 inline bool handleReadError (ssize_t nbytes);
142
144 // This routine is responsible for signalling the User
145 inline bool doProxy ();
146
148 // This routine is responsible for signalling the User
149 inline bool doRead ();
150
152 // This routine is responsible for signalling the User
153 inline bool doWrite ();
154
156 inline void doAccept ();
157
159 void doTLS ();
160
162 inline int doTLSread();
163
165 // returns true if worked, false on SSL error
166 inline int doTLSwrite();
167
169 // returns true if worked, false on SSL error
170 inline int doTLShandshake();
171
173 // returns true if worked, false on SSL error
174 inline int doTLSshutdown();
175
177 inline bool setTrafficClass (
178 endpoint_t fd,
179 int family,
180 unsigned traffic_class);
181
182 protected:
183 ~SocketPoll() override {
184 tidy ();
185 }
186
187 public:
188 SocketPoll () :
189 _poller (0),
190 _state (State_noconnect),
191 _rlen (0),
192 _rfill (false),
193 _rfull (false),
194 _wlen (0),
195 _ssl (0),
196 _hostname (0),
197 _emfile (0),
198 _noshut (false)
199 {
200 _event.Init (this);
201 _timer.Init (this);
202 }
203
205 void Die () override {
206 delete this;
207 }
208
210 inline void tidy () {
211 SetUser (0);
212
213 if ( _ssl != 0 ) {
214 if ( _poller != 0 ) {
215 _poller->Deregister (this);
216 _poller = 0;
217 }
218
219 // This closes the socket
220 int err = SSL_get_error(_ssl, 0);
221 if (err != SSL_ERROR_NONE) {
222 // Report but clear and continue
223 LOG_DEBUG (("SocketPoll::tidy() - SSL error (%d)", err));
224 ERR_clear_error();
225 }
226 SSL_free (_ssl);
227 _ssl = 0;
228
229 _fd = INVALID_ENDPOINT;
230 _event.Cancel ();
231
232 } else if ( _fd != INVALID_ENDPOINT ) {
233 if ( _poller != 0 ) {
234 _poller->Deregister (this);
235 _poller = 0;
236 }
237
238 // This seems to be the way to close sockets cleanly
239 // on Windows. If you use SHUT_RDWR (aka SH_BOTH) the
240 // remote end can be reset.
241 if ( !_noshut )
242 shutdown (_fd, SHUT_WR);
243
244 closesocket (_fd);
245 _fd = INVALID_ENDPOINT;
246
247 _event.Cancel ();
248 }
249
250 _rbuf = _rptr = 0;
251 _rlen = 0;
252 _rfull = false;
253
254 _state = State_noconnect;
255 }
256
258 // If requested make sure endpoint can be inherited
259 endpoint_t GetEndpoint (bool inheriting) override {
260 if ( inheriting ) {
261 _noshut = true;
262
263#ifdef IC_WIN32
264 if ( SetHandleInformation ((HANDLE)_fd,
265 HANDLE_FLAG_INHERIT,
266 HANDLE_FLAG_INHERIT) == 0 ) {
267 MSG_IOevent_Inherit_LOG();
268 }
269
270#elif defined (FD_CLOEXEC)
271 int flags = fcntl (_fd, F_GETFD, 0);
272
273 if ( flags >= 0 ) {
274 flags &= ~FD_CLOEXEC;
275 if ( fcntl (_fd, F_SETFD, flags) != 0 ) {
276 MSG_IOevent_Inherit_LOG ();
277 }
278 }
279#endif
280 }
281 return _fd;
282 }
283
285 unsigned Events () override {
286 return _uevents;
287 }
288
290 int GetLocalAddress (struct sockaddr *laddr,
291 socklen_t *lalenp,
292 MSGstruct *msp) override {
293
294 if ( _fd == INVALID_ENDPOINT ) {
295 MSG_IOevent_NotConnected_SET (msp);
296 return MSG_IOevent_NotConnected;
297 }
298
299#ifdef GETSOCKNAME_NEEDS_INTP
300 int lalen;
301#else
302 socklen_t lalen;
303#endif
304 lalen = *lalenp;
305 if ( getsockname (_fd, laddr, &lalen) != 0 ) {
306 *lalenp = lalen;
307 MSG_IOevent_IOerror_SET (msp, "getsockname");
308 return MSG_IOevent_IOerror;
309 }
310
311 // In case encapsulated IPv4 address
312 *lalenp = convert2ipv4 (laddr, lalen);
313 return 0;
314 }
315
317 int GetPeerAddress (struct sockaddr *laddr,
318 socklen_t *lalenp,
319 MSGstruct *msp) override {
320
321 if ( _fd == INVALID_ENDPOINT ) {
322 MSG_IOevent_NotConnected_SET (msp);
323 return MSG_IOevent_NotConnected;
324 }
325
326#ifdef GETPEERNAME_NEEDS_INTP
327 int lalen;
328#else
329 socklen_t lalen;
330#endif
331 lalen = *lalenp;
332 if ( getpeername (_fd, laddr, &lalen) != 0 ) {
333 *lalenp = lalen;
334 MSG_IOevent_IOerror_SET (msp, "getpeername");
335 return MSG_IOevent_IOerror;
336 }
337
338 // In case encapsulated IPv4 address
339 *lalenp = convert2ipv4 (laddr, lalen);
340 return 0;
341 }
342
344 TLS_CipherSuite GetCipherSuite () override {
345 if ( _state != State_tls || _ssl == 0 )
346 return TLS_NULL_WITH_NULL_NULL;
347
348 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
349 return SSLTLS::cipher_id(cipher);
350 }
351
353 X509* GetPeerCertificate () override {
354 if ( _state != State_tls || _ssl == 0 )
355 return 0;
356
357 return SSL_get_peer_certificate(_ssl);
358 }
359
361 // This is virtual so that each subclass can override
362 virtual SocketPoll *Clone () = 0;
363
364 // Since the interface will be protected,
365 // We need specific functions for each of the deliver cases
366
368 void actualDeliver (time_t *msg);
369
371 void actualDeliver (::Poll::pollmsg *msg) override;
372
373 // Interface to stream user
375 void actualDeliver (External *ext);
376
378 void actualDeliver (ConnectRequest *req);
379
381 void actualDeliver (ListenRequest *req);
382
385
388
390 void actualDeliver (DataRequest *req);
391
393 void actualDeliver (ReadRequest *req);
394
396 void actualDeliver (StartTLS *req);
397
399 void actualDeliver (StreamControl *option);
400
402 virtual void Deliver (time_t *msg) {
403 actualDeliver (msg);
404 }
405
406 // Interface from poll provider
407
409 void Deliver (::Poll::pollmsg *msg) override {
410 actualDeliver (msg);
411 }
412
413 // Interface to stream user
415 void Deliver (External *ext) override {
416 actualDeliver (ext);
417 }
418
420 void Deliver (ConnectRequest *req) override {
421 actualDeliver (req);
422 }
423
425 void Deliver (ListenRequest *req) override {
426 actualDeliver (req);
427 }
428
430 void Deliver (ConnectAccept *req) override {
431 actualDeliver (req);
432 }
433
435 void Deliver (DisconnectRequest *req) override {
436 actualDeliver (req);
437 }
438
440 void Deliver (DataRequest *req) override {
441 actualDeliver (req);
442 }
443
445 void Deliver (ReadRequest *req) override {
446 actualDeliver (req);
447 }
448
450 void Deliver (StartTLS *req) override {
451 actualDeliver (req);
452 }
453
455 void Deliver (StreamControl *option) override {
456 actualDeliver (option);
457 }
458
460 void Deliver (LengthFnxRequest *) override {
461 // Don't bother to synchronize this
462 }
463 };
464
466 class SyncSocketPoll : public Syncmsgobj<SocketPoll> {
467 protected:
468 ~SyncSocketPoll () override {
469 // Need to call tidy() here to ensure stuff is cleared up
470 // while this actual object exists.
471 tidy();
472 }
473
474 public:
475 // for Deliver(Stream::LengthFnxRequest*)
477
479 SocketPoll *Clone () override {
480 return new SyncSocketPoll ();
481 }
482
484 void Die () override {
485 dieAux ();
486 }
487
489 void Deliver (time_t *msg) override {
490 actualDeliver (msg);
491 }
492
494 void Deliver (::Poll::pollmsg *msg) override {
495 msgDeliver (msg);
496 }
497
498 // Interface to stream user
500 void Deliver (External *ext) override {
501 msgDeliver (ext);
502 }
503
505 void Deliver (ConnectRequest *req) override {
506 msgDeliver (req);
507 }
508
510 void Deliver (ListenRequest *req) override {
511 msgDeliver (req);
512 }
513
515 void Deliver (ConnectAccept *req) override {
516 msgDeliver (req);
517 }
518
520 void Deliver (DisconnectRequest *req) override {
521 msgDeliver (req);
522 }
523
525 void Deliver (DataRequest *req) override {
526 msgDeliver (req);
527 }
528
530 void Deliver (ReadRequest *req) override {
531 msgDeliver (req);
532 }
533
535 void Deliver (StartTLS *req) override {
536 msgDeliver (req);
537 }
538
540 void Deliver (StreamControl *option) override {
541 msgDeliver (option);
542 }
543 };
544}
545
546// SocketPoll implementation
547
548inline void Stream::SocketPoll::waitEvent (unsigned events)
549{
550 StatusIndication statusind (this);
551
552 if ( _fd == INVALID_ENDPOINT )
553 return;
554
555 if ( _poller == 0 ) {
557
558 if ( _poller == 0 ) {
559 MSG_IOevent_NoPollProvider_SET (&statusind.msg);
560 GetUser()->Deliver (&statusind);
561 tidy ();
562 return;
563 }
564
565 int rc = _poller->Register (this);
566
567 if ( rc != 0 ) {
568 MSG_IOevent_PollRegister_SET (&statusind.msg, rc);
569 GetUser()->Deliver (&statusind);
570 tidy ();
571 return;
572 }
573 }
574
575 _uevents |= events;
576
577 // If have events which the poller is not already listening for,
578 // tell it to listen
579 if ( _uevents & ~_pevents )
580 _poller->Control (this);
581}
582
583bool Stream::SocketPoll::doWrite ()
584{
585 ssize_t remain = (ssize_t)_wlen - (_wptr - _wbuf);
586 ssize_t tosend = remain;
587 ssize_t nbytes;
588
589 LOG_DEBUG (("SocketPoll::doWrite() - send %ld", (long)tosend));
590
591 while (1) {
592 nbytes = send (_fd, _wptr, tosend, 0);
593
594 if ( nbytes <= 0 ) {
595 StatusIndication statusind (this);
596
597 if ( nbytes == 0 ) {
598 // EOF
599 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
600 break;
601 } else {
602 isode_set_errno();
603 // If error is that read would block, then just return
604 // Caller should ensure that poller knows we want to
605 // know when readable.
606 if ( wouldBlock () )
607 return false;
608#ifdef IC_WIN32
609 // On Windows we may get WSAENOBUFS (converted to ENOBUFS in isode_set_errno)
610 // if the data we are attempting to send is 'too big'
611 if (errno == ENOBUFS) {
612 // Try and send half as much data....
613 tosend = tosend / 2;
614 LOG_DEBUG (("SocketPoll::doWrite() - retry send with %d", tosend));
615 }
616
617 if ((tosend == 0) || (errno != ENOBUFS)) {
618 // Error!
619 MSG_IOevent_IOerror_SET (&statusind.msg, "send");
620 break;
621 }
622 continue;
623#else
624 // Error
625 MSG_IOevent_IOerror_SET (&statusind.msg, "send");
626 break;
627#endif
628 }
629
630 GetUser()->Deliver (&statusind);
631
632 tidy ();
633
634 return true;
635 } else {
636 break;
637 }
638 }
639
640 _wptr += nbytes;
641 remain -= nbytes;
642
643 if ( remain == 0 ) {
644 ReleaseBuf release;
645
646 release.buf = _wbuf;
647 release.len = _wptr - _wbuf;
648
649 _wbuf = _wptr = 0;
650 _wlen = 0;
651
652 GetUser()->Deliver (&release);
653
654 return true;
655 }
656
657 // Presume that the reason the write was incomplete is that
658 // the next attempt would block
659 return false;
660}
661
662void Stream::SocketPoll::handleProxyError() {
663 Stream::StatusIndication statusind (this);
664 MSG_IOevent_IOerror_SET (&statusind.msg, "PROXY");
665 GetUser()->Deliver (&statusind);
666 tidy ();
667}
668
669bool Stream::SocketPoll::handleReadError (ssize_t nbytes)
670{
671 StatusIndication statusind (this);
672
673 if ( nbytes == 0 ) {
674 // EOF
675 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
676 } else {
677 isode_set_errno();
678 // If error is that read would block, then just return
679 // Caller should ensure that poller knows we want to
680 // know when readable.
681 if ( wouldBlock () )
682 return false;
683
684 // Error
685 MSG_IOevent_IOerror_SET (&statusind.msg, "recv");
686 }
687
688 GetUser()->Deliver (&statusind);
689
690 tidy ();
691
692 return true;
693}
694
695bool Stream::SocketPoll::doProxy ()
696{
697 if (!proxybuf_) {
698 proxybuf_ = ProxyBuf();
699 }
700
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));
704
705 ProxyBuf& pb = *proxybuf_;
706 while (true) {
707 char b;
708 ssize_t len;
709 switch (pb.state) {
710 case ProxyBuf::State::BEGIN: {
711 len = recv (_fd, &b, 1, 0);
712 if (1 == len) {
713 switch (b) {
714 case 'P':
715 pb.version = ProxyBuf::Version::VERS_1;
716 pb.buf.reserve(108);
717 pb.buf.push_back(b);
718 pb.state = ProxyBuf::State::HEADER;
719 break;
720 case '\x0D':
721 pb.version = ProxyBuf::Version::VERS_2;
722 pb.buf.resize(16);
723 pb.buf[0] = b;
724 pb.state = ProxyBuf::State::HEADER;
725 pb.header_read = 1;
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));
729 break;
730 default:
731 MSG_IOevent_ProxyError_LOG(b, _fd, "Unknown PROXY version");
732 handleProxyError();
733 return true;
734 }
735 } else {
736 return handleReadError(len);
737 }
738 }
739 FALLTHROUGH;
740 case ProxyBuf::State::HEADER:
741 switch (pb.version) {
742 case ProxyBuf::Version::VERS_1:
743 len = recv (_fd, &b, 1, 0);
744 if (1 == len) {
745 if (b == '\r') {
746 pb.buf.push_back(b);
747 continue;
748 }
749
750 if (b == '\n') {
751 if (pb.buf[pb.buf.length() - 1] != '\r') {
752 MSG_IOevent_ProxyError_LOG(1, _fd, "read CR but previous character was not newline");
753 handleProxyError();
754 return true;
755 }
756
757 pb.buf.push_back(b);
758 pb.state = ProxyBuf::State::HEADER_DONE;
759 continue;
760 }
761
762 if (isascii(b)) {
763 pb.buf.push_back(b);
764 continue;
765 }
766
767 MSG_IOevent_ProxyError_LOG(1, _fd, "read a non-ascii character");
768 handleProxyError();
769 return true;
770
771 } else {
772 return handleReadError(len);
773 }
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);
777 if (len <= 0) {
778 return handleReadError(len);
779 }
780
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");
787 handleProxyError();
788 return true;
789 }
790 pb.remaining = ntohs(ph->len);
791 pb.header_len = 16 + pb.remaining;
792 if (pb.remaining > 520) {
793 // Way too big!
794 MSG_IOevent_ProxyError_LOG(2, _fd, "length is much too big");
795 handleProxyError();
796 return true;
797 }
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));
802 continue;
803 }
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));
807 return false;
808 }
809 }
810 FALLTHROUGH;
811 case ProxyBuf::State::HEADER_BODY:
812 len = recv (_fd, &(*pb.buf.begin()) + pb.header_read, pb.remaining, 0);
813 if (len <= 0) {
814 return handleReadError(len);
815 }
816 pb.remaining -= 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));
823 } else {
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));
827 return false;
828 }
829 FALLTHROUGH;
830 case ProxyBuf::State::HEADER_DONE: {
831 if (pb.version == ProxyBuf::Version::VERS_1) {
832 // Chop off the CR LF
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");
836 handleProxyError();
837 return true;
838 }
839 pb.buf = pb.buf.substr(6);
840 if (starts_with(pb.buf, "LOCAL ")) {
841 // We should probably parse the rest of the line, but
842 // assume it's OK. This is used by the PROXY server
843 // (for health checking the server)
844 pb.local = true;
845
846 } else if (starts_with(pb.buf, "TCP4 ")) {
847 ipv4_addr pa;
848 if (!read_proxy_ipv4(pb.buf.substr(5), pa)) {
849 MSG_IOevent_ProxyError_LOG(1, _fd, "failed to decode TCP4 header");
850 handleProxyError();
851 return true;
852 }
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);
857
858 } else if (starts_with(pb.buf, "TCP6 ")) {
859 ipv6_addr pa;
860 if (!read_proxy_ipv6(pb.buf.substr(5), pa)) {
861 MSG_IOevent_ProxyError_LOG(1, _fd, "failed to decode TCP6 header");
862 handleProxyError();
863 return true;
864 }
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);
869
870 } else {
871 MSG_IOevent_ProxyError_LOG(1, _fd, "second word was not LOCAL, TCP4, or TCP6");
872 handleProxyError();
873 return true;
874 }
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;
878 if (0x0 == cmd) {
879 // This is a local command, so just allow it
880 pb.local = true;
881 } else {
882 if (0x1 != cmd) {
883 // Something other than PROXY, so we drop the connection
884 MSG_IOevent_ProxyError_LOG(2, _fd, "command was not LOCAL or PROXY");
885 handleProxyError();
886 return true;
887 }
888
889 if ((ph->fam & 0x0f) != 0x1) {
890 // we only support STREAM
891 MSG_IOevent_ProxyError_LOG(2, _fd, "non-STREAM transport protocol");
892 handleProxyError();
893 return true;
894 }
895
896 switch (ph->fam & 0xf0) {
897 case 0x10: {
898 if (pb.header_len < 16 + sizeof(ipv4_addr)) {
899 MSG_IOevent_ProxyError_LOG(2, _fd, "message length too small to hold TCP4 information");
900 handleProxyError();
901 return true;
902 }
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;
908 break;
909 }
910 case 0x20: {
911 if (pb.header_len < 16 + sizeof(ipv6_addr)) {
912 MSG_IOevent_ProxyError_LOG(2, _fd, "message length too small to hold TCP6 information");
913 handleProxyError();
914 return true;
915 }
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;
921 break;
922 }
923 default:
924 // Anything else we'll ignore (LOCAL is accepted earlier)
925 MSG_IOevent_ProxyError_LOG(2, _fd, "unknown family");
926 handleProxyError();
927 return true;
928 }
929 }
930 }
931
932 if (!pb.local && pb.raddr.ss_family == AF_UNSPEC) {
933 MSG_IOevent_ProxyError_LOG(-1, _fd, "unable to determine remote address family");
934 handleProxyError();
935 } else {
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));
940
941 // Reset read buffer
942 _rbuf = _rptr = 0;
943 _rlen = 0;
944
945 ProxyIndication proxyind;
946 proxyind.local = pb.local;
947 proxyind.raddr = reinterpret_cast<sockaddr *>(&pb.raddr);
948 GetUser()->DeliverProxy (&proxyind);
949 }
950 return true;
951 }
952 }
953 }
954 return true;
955}
956
957bool Stream::SocketPoll::doRead ()
958{
959 ssize_t remain = (ssize_t)_rlen - (_rptr - _rbuf);
960
961 LOG_DEBUG (("doRead: _rlen=%d remain=%d", (int)_rlen, (int)remain));
962
963 ssize_t nbytes = recv (_fd, _rptr, remain, 0);
964
965 LOG_DEBUG (("doRead: recv -> %d", (int)nbytes));
966
967 if ( nbytes <= 0 ) {
968 return handleReadError (nbytes);
969 }
970
971 // The read filled the buffer - there may be more queued
972 if ( nbytes == remain )
973 _rfull = true;
974
975 _rptr += nbytes;
976 remain -= nbytes;
977
978 LOG_DEBUG (("doRread: remain=%d _rfill=%d", (int)remain, _rfill));
979
980 // If not filling buffer or the buffer is full, send
981 // data indication
982 if ( !_rfill || remain == 0 ) {
983 DataIndication dataind;
984
985 dataind.buf = _rbuf;
986 dataind.len = _rptr - _rbuf;
987
988 _rbuf = _rptr = 0;
989 _rlen = 0;
990
991 GetUser()->Deliver (&dataind);
992
993 return true;
994 }
995
996 // Need to read some more
997 return false;
998}
999
1000void Stream::SocketPoll::doAccept ()
1001{
1002 StatusIndication statusind (this);
1003 char abuf[MAXSOCKADDRLEN];
1004#ifdef ACCEPT_NEEDS_INTP
1005 int alen;
1006#else
1007 socklen_t alen;
1008#endif
1009 alen = sizeof abuf;
1010
1011 endpoint_t newfd = accept (_fd, (struct sockaddr *)abuf, &alen);
1012 if (INVALID_ENDPOINT == newfd) {
1013 isode_set_errno();
1014 // Note: need to distinguish the serious cases where accept should
1015 // not have been called, and failures of the individual accept.
1016 switch ( errno ) {
1017 default:
1018 // Note: could get repeating errors here. E.g. if at limit of
1019 // number of open files for the process or system.
1020 MSG_IOevent_AcceptError_SET (&statusind.msg);
1021 MSGappendsyserror (&statusind.msg);
1022 GetUser()->Deliver (&statusind);
1023 break;
1024
1025 case EMFILE:
1026 // No point in trying again immediately, as it would spin
1027 // Notify user and wait for a while before trying again
1028 MSG_IOevent_AcceptError_SET (&statusind.msg);
1029 MSGappendsyserror (&statusind.msg);
1030 GetUser()->Deliver (&statusind);
1031 {
1032 time_t dummy = 0;
1033 _emfile++;
1034 if ( _emfile > 100 ) _emfile = 100;
1035
1036 _timer.Sendms (100*_emfile, dummy); // 100 ms times # errors
1037 }
1038 return;
1039
1040 case EBADF:
1041 case EINVAL:
1042#ifdef ENOTSOCK
1043 case ENOTSOCK:
1044#endif
1045#ifdef EOPNOTSUPP
1046 case EOPNOTSUPP:
1047#endif
1048#ifdef EFAULT
1049 case EFAULT:
1050#endif
1051 // A severe error, abandon listen
1052 MSG_IOevent_IOerror_SET (&statusind.msg, "accept");
1053 GetUser()->Deliver (&statusind);
1054 tidy ();
1055 return;
1056
1057#ifdef EINTR
1058 case EINTR:
1059#endif
1060#ifdef EAGAIN
1061 case EAGAIN:
1062#endif
1063#if defined(EWOULDBLOCK)
1064# if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
1065 case EWOULDBLOCK:
1066# endif
1067#endif
1068 // False alarm
1069 break;
1070 }
1071 } else {
1072 // Have new connection from peer
1073#ifdef IC_WIN32
1074 // Windows sockets are inherited by default
1075 if ( SetHandleInformation(
1076 (HANDLE)newfd,
1077 HANDLE_FLAG_INHERIT, // mask of bits to change
1078 0) == 0 ) {
1079 MSG_IOevent_Inherit_LOG();
1080 }
1081#elif defined (FD_CLOEXEC)
1082 (void) fcntl(newfd, F_SETFD, FD_CLOEXEC);
1083#endif
1084
1085 bool do_setsockopt = true;
1086#ifdef O_NONBLOCK
1087 if ( fcntl(newfd, F_SETFL, O_NONBLOCK) != 0 ) {
1088 closesocket(newfd);
1089 MSG_IOevent_IoctlError_SET(&statusind.msg);
1090 MSGappendsyserror(&statusind.msg);
1091 GetUser()->Deliver(&statusind);
1092 do_setsockopt = false;
1093 }
1094#elif defined(FIONBIO)
1095 char onoff = 1;
1096 if ( ioctl(newfd, FIONBIO, &onoff) != 0 ) {
1097 closesocket(newfd);
1098 MSG_IOevent_IoctlError_SET(&statusind.msg);
1099 MSGappendsyserror(&statusind.msg);
1100 GetUser()->Deliver(&statusind);
1101 do_setsockopt = false;
1102 }
1103#else
1104#error Cannot set socket into non-blocking more
1105#endif
1106 if (do_setsockopt) {
1107#ifdef TCP_NODELAY
1108 // Always set this on by default
1109#ifdef IC_WIN32
1110 char nodelay = 1;
1111#else
1112 int nodelay = 1;
1113#endif
1114 // But ignore failure
1115 setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof nodelay);
1116#endif
1117 // Always set keepalives (and ignore failure)
1118#ifdef IC_WIN32
1119 char keepalive = 1;
1120#else
1121 int keepalive = 1;
1122#endif
1123 setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive, sizeof keepalive);
1124
1126 Stream::SocketPoll * newprov = Clone();
1127
1128 connind.listener = this;
1129 connind.newprovider = newprov;
1130
1131 newprov->_fd = newfd;
1132 newprov->_state = State_accepting;
1133
1134 memcpy(&newprov->_caddr, abuf, alen);
1135 newprov->_clen = alen;
1136
1137 connind.saddr = reinterpret_cast<struct sockaddr *>(&newprov->_caddr);
1138 connind.salen = convert2ipv4(reinterpret_cast<struct sockaddr *>(&newprov->_caddr), alen);
1139
1140#ifdef GETSOCKNAME_NEEDS_INTP
1141 int llen;
1142#else
1143 socklen_t llen;
1144#endif
1145 llen = sizeof newprov->_laddr;
1146 newprov->_llen = sizeof newprov->_laddr;
1147
1148 getsockname(newfd, reinterpret_cast<struct sockaddr *>(&newprov->_laddr), &llen);
1149
1150 newprov->_llen = llen;
1151
1152 connind.laddr = reinterpret_cast<struct sockaddr *>(&newprov->_laddr);
1153 connind.lalen = newprov->_llen;
1154
1155 GetUser()->Deliver(&connind);
1156 }
1157 }
1158
1159 // Accept did not fail or have EMFILE
1160 _emfile = 0;
1161
1162 // Go back for more
1163 waitEvent (::Poll::Event_In);
1164}
1165
1166
1167int Stream::SocketPoll::doTLSread ()
1168{
1169 int remain = (int)_rlen - (_rptr - _rbuf);
1170
1171 LOG_DEBUG (("doTLSread: _rlen=%d remain=%d", (int)_rlen, (int)remain));
1172
1173 int nbytes = SSL_read (_ssl, _rptr, remain);
1174
1175 LOG_DEBUG (("doTLSread: SSL_read -> %d", nbytes));
1176
1177 // SSL errors handled by caller
1178 if ( nbytes < 0 )
1179 return nbytes;
1180
1181 if ( nbytes == 0 ) {
1182 StatusIndication statusind (this);
1183
1184 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1185
1186 GetUser()->Deliver (&statusind);
1187
1188 _tlsstate = TLS_idle;
1189
1190 tidy ();
1191 return 1; // Fudge to stop error handling
1192 }
1193
1194 // The read filled the buffer - there may be more queued
1195 if ( nbytes == remain )
1196 _rfull = true;
1197
1198 _rptr += nbytes;
1199 remain -= nbytes;
1200
1201 LOG_DEBUG (("doTLSread: remain=%d _rfill=%d", (int)remain, _rfill));
1202
1203 // If not filling buffer or the buffer is full, send
1204 // data indication
1205 if ( !_rfill || remain == 0 ) {
1206 DataIndication dataind;
1207
1208 dataind.buf = _rbuf;
1209 dataind.len = _rptr - _rbuf;
1210
1211 _rbuf = _rptr = 0;
1212 _rlen = 0;
1213
1214 _tlsstate = TLS_idle;
1215
1216 GetUser()->Deliver (&dataind);
1217 }
1218
1219 return nbytes;
1220}
1221
1222int Stream::SocketPoll::doTLSwrite ()
1223{
1224 int remain = (int)_wlen - (_wptr - _wbuf);
1225 LOG_DEBUG (("doTLSwrite: _wlen=%d remain=%d", (int)_wlen, (int)remain));
1226
1227 int nbytes = SSL_write (_ssl, _wptr, remain);
1228 LOG_DEBUG (("doTLSwrite: SSL_write -> %d", nbytes));
1229
1230 // Errors handled in caller
1231 if ( nbytes <= 0 )
1232 return nbytes;
1233
1234 _wptr += nbytes;
1235 remain -= nbytes;
1236
1237 if ( remain == 0 ) {
1238 ReleaseBuf release;
1239
1240 release.buf = _wbuf;
1241 release.len = _wptr - _wbuf;
1242
1243 _wbuf = _wptr = 0;
1244 _wlen = 0;
1245
1246 GetUser()->Deliver (&release);
1247
1248 _tlsstate = TLS_idle;
1249 }
1250
1251 return nbytes;
1252}
1253
1254int Stream::SocketPoll::doTLShandshake ()
1255{
1256 int rc = SSL_do_handshake (_ssl);
1257 LOG_DEBUG (("doTLShandshake: SSL_do_handshake -> %d", rc));
1258
1259 if ( rc < 0 )
1260 return rc;
1261
1262 StatusIndication statusind (this);
1263
1264 if ( rc == 0 ) {
1265 _tlsstate = TLS_idle;
1266
1267 return 0;
1268 }
1269
1270 _tlsstate = TLS_idle;
1271
1272 const char *version = SSL_get_version(_ssl);
1273
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);
1277
1278 X509 *peer = SSL_get_peer_certificate(_ssl);
1279
1280 bool closing = true;
1281
1282 MSGstruct submsg;
1283
1284 if ( !peer ) {
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);
1289
1290 } else {
1291 MSG_IOevent_SSLOK_SET (&statusind.msg,
1292 version, cs, strength);
1293
1294 closing = false;
1295 }
1296
1297 } else if ( _choice == SSLTLS::tls_verify_none ) {
1298 MSG_IOevent_SSLOK_SET (&statusind.msg,
1299 version, cs, strength);
1300
1301 closing = false;
1302
1303 } else {
1304
1305 X509_NAME *subject_name = X509_get_subject_name(peer);
1306
1307 long result = SSL_get_verify_result(_ssl);
1308 char *peername = X509_NAME_to_text (subject_name);
1309
1310 switch (result) {
1311 case X509_V_OK:
1312 closing = false;
1313 MSG_IOevent_SSLverified_SET (&statusind.msg,
1314 version, cs, strength,
1315 peername);
1316 break;
1317
1318 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1319 MSG_IOevent_SSLnoissuercert_SET (&submsg);
1320 break;
1321 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1322 MSG_IOevent_SSLcertdecryptfailed_SET (&submsg);
1323 break;
1324 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1325 MSG_IOevent_SSLcertsignature_SET (&submsg);
1326 break;
1327 case X509_V_ERR_CERT_NOT_YET_VALID:
1328 MSG_IOevent_SSLcertnotyetvalid_SET (&submsg);
1329 break;
1330 case X509_V_ERR_CERT_HAS_EXPIRED:
1331 MSG_IOevent_SSLcertexpired_SET (&submsg);
1332 break;
1333 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1334 MSG_IOevent_SSLcertnotbefore_SET (&submsg);
1335 break;
1336 case X509_V_ERR_OUT_OF_MEM:
1337 MSG_Base_Nomem_SET (&submsg, 0);
1338 break;
1339 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1340 MSG_IOevent_SSLselfsigned_SET (&submsg);
1341 break;
1342 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1343 MSG_IOevent_SSLlocalissuer_SET (&submsg);
1344 break;
1345 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1346 MSG_IOevent_SSLleafsignature_SET (&submsg);
1347 break;
1348 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1349 MSG_IOevent_SSLchaintoolong_SET (&submsg);
1350 break;
1351 case X509_V_ERR_INVALID_CA:
1352 MSG_IOevent_SSLinvalidCA_SET (&submsg);
1353 break;
1354 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1355 MSG_IOevent_SSLpathlength_SET (&submsg);
1356 break;
1357 case X509_V_ERR_INVALID_PURPOSE:
1358 MSG_IOevent_SSLinvalidpurpose_SET (&submsg);
1359 break;
1360 case X509_V_ERR_CERT_UNTRUSTED:
1361 MSG_IOevent_SSLuntrusted_SET (&submsg);
1362 break;
1363 case X509_V_ERR_CERT_REJECTED:
1364 MSG_IOevent_SSLrejected_SET (&submsg);
1365 break;
1366 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
1367 MSG_IOevent_SSLsubjectissuer_SET (&submsg);
1368 break;
1369 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
1370 MSG_IOevent_SSLserialmismatch_SET (&submsg);
1371 break;
1372 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
1373 MSG_IOevent_SSLkeyusage_SET (&submsg);
1374 break;
1375 default:
1376 MSG_IOevent_SSLunknown_SET (&submsg, result);
1377 break;
1378 }
1379
1380 if ( closing ) {
1381 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
1382 MSGappend (&statusind.msg, &submsg);
1383 }
1384
1385 if (x509_acceptable_name(subject_name) != OK) {
1386 closing = true;
1387 MSG_IOevent_SSLnul_in_subject_LOG(peername);
1388 }
1389
1390 if ( peername != 0 )
1391 free (peername);
1392 }
1393
1394 if ( peer ) {
1395 if (!closing && _hostname &&
1396 SSLTLS::CheckHostname (peer, _hostname, &statusind.msg) != OK ) {
1397 closing = true;
1398 }
1399
1400 X509_free(peer);
1401 }
1402
1403 _tlsstate = TLS_idle;
1404
1405 GetUser()->Deliver (&statusind);
1406
1407 if ( closing )
1408 tidy ();
1409
1410 return rc;
1411}
1412
1413int Stream::SocketPoll::doTLSshutdown ()
1414{
1415 int rc = SSL_shutdown (_ssl);
1416 LOG_DEBUG (("SocketPoll::doTLSshutdown() -> %d", rc));
1417
1418 if ( rc <= 0 ) {
1419 if (rc == 0) {
1420 LOG_DEBUG (("SocketPoll::doTLSshutdown() - shutdown in progress"));
1421 } else {
1422 int err = SSL_get_error(_ssl, rc);
1423 LOG_DEBUG (("SocketPoll::doTLSshutdown() - SSL error (%d)", err));
1424 }
1425 return rc;
1426 }
1427
1428 // Shutdown successful, tell user
1429
1430 StatusIndication statusind (this);
1431 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1432 GetUser()->Deliver (&statusind);
1433
1434 // Close up connection, etc.
1435 _tlsstate = TLS_idle;
1436 tidy ();
1437
1438 return rc;
1439}
1440
1441void Stream::SocketPoll::doTLS ()
1442{
1443 LOG_DEBUG (("SocketPoll::doTLS()"));
1444 for (;;) {
1445 int rc = 0;
1446
1447 // If there is no SSL, then the connection is being closed down
1448 if ( _ssl == 0 )
1449 return;
1450
1451 switch ( _tlsstate ) {
1452 case TLS_idle:
1453 if ( _wlen != 0 ) {
1454 _tlsstate = TLS_write;
1455 rc = doTLSwrite();
1456
1457 } else if ( _rlen != 0 ) {
1458 rc = doTLSread();
1459
1460 } else {
1461 return;
1462 }
1463 break;
1464
1465 case TLS_write:
1466 rc = doTLSwrite();
1467 break;
1468
1469 case TLS_handshake:
1470 rc = doTLShandshake();
1471 break;
1472
1473 case TLS_close:
1474 rc = doTLSshutdown();
1475 break;
1476 }
1477
1478 if ( rc > 0 ) continue;
1479
1480 StatusIndication statusind (this);
1481
1482 switch (SSL_get_error(_ssl, rc)) {
1483 case SSL_ERROR_NONE:
1484 // No problem, carry on
1485 continue;
1486
1487 case SSL_ERROR_ZERO_RETURN:
1488 // Connection has been closed
1489 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1490 break;
1491
1492 case SSL_ERROR_WANT_READ:
1493 waitEvent (::Poll::Event_In);
1494 return;
1495
1496 case SSL_ERROR_WANT_WRITE:
1497 waitEvent (::Poll::Event_Out);
1498 return;
1499
1500 case SSL_ERROR_SYSCALL:
1501 // Check the error queue
1502 if (ERR_get_error()==0) {
1503 if (rc == 0) {
1504 // Connection has closed
1505 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1506 } else {
1507 MSG_IOevent_IOerror_SET (&statusind.msg, "SSL");
1508 }
1509 } else {
1510 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, "SSL_ERROR_SYSCALL");
1511 }
1512 break;
1513
1514 case SSL_ERROR_SSL:
1515 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, "SSL_ERROR_SSL");
1516 break;
1517
1518 case SSL_ERROR_WANT_CONNECT:
1519 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,"SSL_WANT_CONNECT");
1520 break;
1521
1522 case SSL_ERROR_WANT_ACCEPT:
1523 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,"SSL_WANT_ACCEPT");
1524 break;
1525
1526 default:
1527 {
1528 char buf[32];
1529 snprintf (buf, sizeof buf, "err=%d", SSL_get_error(_ssl, rc));
1530 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, buf);
1531 break;
1532 }
1533 }
1534
1535 GetUser()->Deliver (&statusind);
1536 tidy();
1537 return;
1538 }
1539}
1540
1542{
1543 // Timer has expired after EMFILE, try again
1544 waitEvent (::Poll::Event_In);
1545}
1546
1548{
1549 if ( checkUser() ) return;
1550
1551 StatusIndication statusind (this);
1552
1553 LOG_DEBUG (("SocketPoll::actualDeliver (pollmsg = %x) state=%d",
1554 msg->events, _state));
1555
1556 // Poller is no longer listening for any events
1557 _pevents = 0;
1558
1559 if ( (msg->events & ::Poll::Event_Terminate) ) {
1560 // System terminating
1561 _uevents = 0;
1562
1563 // Close first, otherwise calls back to poller
1564 closesocket (_fd);
1565 _fd = INVALID_ENDPOINT;
1566 _poller = 0;
1567
1568 // Tell User
1569 MSG_IOevent_Terminating_SET (&statusind.msg);
1570 GetUser()->Deliver (&statusind);
1571
1572 return;
1573 }
1574
1575 if ( msg->events &
1576 (::Poll::Event_Err | ::Poll::Event_Hup | ::Poll::Event_Nval) ) {
1577
1578 // Don't want any events
1579 _uevents = 0;
1580
1581 // Get error from socket
1582 int eno;
1583#ifdef GETSOCKOPT_NEEDS_INTP
1584 int olen;
1585#else
1586 socklen_t olen;
1587#endif
1588 olen = sizeof eno;
1589
1590 /* Casting to (char *) is required for Windows */
1591 int rc = getsockopt (_fd, SOL_SOCKET, SO_ERROR, (char *)&eno, &olen);
1592
1593 const char *argv[1];
1594 argv[0] = "poll";
1595
1596 MSGsetv (&statusind.msg, MSG_IOevent_IOerror, 1, argv);
1597
1598 if ( rc == 0 ) {
1599 MSGstruct sockerr;
1600 MSGsetv (&sockerr,
1601 MSGID_BUILD(MSGLEVEL_ERROR, MSGID_SYSFAC, eno),
1602 0, 0);
1603 MSGappend (&statusind.msg, &sockerr);
1604 } else {
1605 MSGappendsyserror (&statusind.msg);
1606 }
1607
1608 GetUser()->Deliver (&statusind);
1609
1610 tidy ();
1611
1612 return;
1613 }
1614
1615 // Cancel desired events
1616 _uevents &= ~msg->events;
1617
1618 if ( msg->events & ::Poll::Event_In ) {
1619
1620 switch ( _state ) {
1621 case State_tls:
1622 doTLS();
1623 break;
1624
1625 case State_need_proxy:
1626 if ( !doProxy() )
1627 waitEvent (::Poll::Event_In);
1628 break;
1629 case State_connected:
1630 LOG_DEBUG (("Read stuff: _rlen = %d", (int)_rlen));
1631 if ( _rlen != 0 ) {
1632 // Stuff to read. If does not complete, then wait again
1633 if ( !doRead () )
1634 waitEvent (::Poll::Event_In);
1635 }
1636 break;
1637
1638 case State_listening:
1639 doAccept ();
1640 break;
1641
1642 default:
1643 break;
1644 }
1645 }
1646
1647 if ( msg->events & ::Poll::Event_Out ) {
1648
1649 switch ( _state ) {
1650 case State_tls:
1651 doTLS();
1652 break;
1653
1654 case State_need_proxy:
1655 // Unexpected state at this point, fall through to connected
1656 LOG_DEBUG (("Need proxy state seen when writing"));
1657 FALLTHROUGH;
1658 case State_connected:
1659 if ( _wlen != 0 ) {
1660 // Stuff to write. If does not complete, then wait again
1661 if ( !doWrite () )
1662 waitEvent (::Poll::Event_Out);
1663 }
1664 break;
1665
1666 case State_connecting:
1667 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
1668 MSG_IOevent_Connected_SET (&statusind.msg);
1669 GetUser()->Deliver (&statusind);
1670 break;
1671
1672 default:
1673 break;
1674 }
1675 }
1676
1677 if ( (_uevents & ~_pevents) && _poller )
1678 _poller->Control (this);
1679}
1680
1682{
1683 if ( checkUser() ) return;
1684
1685 StatusIndication statusind (this);
1686
1687 LOG_DEBUG (("SocketPoll::actualDeliver (External)"));
1688
1689 if ( _state != State_noconnect ) {
1690 MSG_IOevent_NotConnected_SET (&statusind.msg);
1691 GetUser()->Deliver (&statusind);
1692 return;
1693 }
1694
1695 _fd = ext->fd;
1696
1697 if ( ext->listen ) {
1698 _state = State_listening;
1699
1700 waitEvent (::Poll::Event_In);
1701
1702 } else {
1703 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
1704 }
1705}
1706
1708{
1709 if ( checkUser() ) return;
1710
1711 StatusIndication statusind (this);
1712
1713 LOG_DEBUG (("SocketPoll::actualDeliver (ConnectRequest)"));
1714
1715 if ( _state != State_noconnect ) {
1716 MSG_IOevent_NotConnected_SET (&statusind.msg);
1717 GetUser()->Deliver (&statusind);
1718 return;
1719 }
1720
1721 int family;
1722#if defined(AF_INET6) && defined(PF_INET6)
1723 struct sockaddr_in6 ipv6addr;
1724#endif
1725
1726 switch ( req->daddr->sa_family ) {
1727#if defined(AF_UNIX) && defined(PF_UNIX)
1728 case AF_UNIX:
1729 family = PF_UNIX;
1730 break;
1731#endif
1732
1733 case AF_INET:
1734 family = PF_INET;
1735 break;
1736
1737#if defined(AF_INET6) && defined(PF_INET6)
1738 case AF_INET6:
1739 family = PF_INET6;
1740 if ( req->dscp != 0 ) {
1741 // Set in the flowinfo in the socket address
1742 ipv6addr = * reinterpret_cast<const struct sockaddr_in6 *>
1743 (req->daddr);
1744
1745 // Note: IPv6 traffic class is offset 20 bits
1746 // and the Codepoint is the top 6 bits.
1747 ipv6addr.sin6_flowinfo = htonl (req->dscp << 22);
1748
1749 req->daddr = reinterpret_cast<struct sockaddr *>(&ipv6addr);
1750 }
1751 break;
1752#endif
1753
1754 default:
1755 MSG_IOevent_AddrType_SET (&statusind.msg, req->daddr->sa_family);
1756 GetUser()->Deliver (&statusind);
1757 return;
1758 }
1759
1760 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1761
1762 if ( fd == INVALID_ENDPOINT ) {
1763 MSG_IOevent_IOerror_SET (&statusind.msg, "socket");
1764 GetUser()->Deliver (&statusind);
1765 return;
1766 }
1767
1768#ifdef IC_WIN32
1769 // Windows sockets are inherited by default
1770 if ( SetHandleInformation ((HANDLE)fd,
1771 HANDLE_FLAG_INHERIT, // mask of bits to change
1772 0) == 0 ) {
1773 MSG_IOevent_Inherit_LOG ();
1774 }
1775#elif defined (FD_CLOEXEC)
1776 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1777#endif
1778
1779#ifdef O_NONBLOCK
1780 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1781 MSG_IOevent_IOerror_SET (&statusind.msg, "fcntl");
1782 GetUser()->Deliver (&statusind);
1783 closesocket (fd);
1784 return;
1785 }
1786#elif defined (FIONBIO)
1787 char onoff = 1;
1788 if ( ioctl (fd, FIONBIO, &onoff) != 0 ) {
1789 MSG_IOevent_IOerror_SET (&statusind.msg, "ioctl");
1790 GetUser()->Deliver (&statusind);
1791 closesocket (fd);
1792 return;
1793 }
1794#else
1795# error Cannot set socket into non-blocking more
1796#endif
1797
1798#ifdef TCP_NODELAY
1799 // Always set this on by default
1800#ifdef IC_WIN32
1801 char nodelay = 1;
1802#else
1803 int nodelay = 1;
1804#endif
1805
1806 // But ignore failure
1807 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof nodelay);
1808#endif
1809
1810 // Always set keepalives (and ignore failure)
1811#ifdef IC_WIN32
1812 char keepalive = 1;
1813#else
1814 int keepalive = 1;
1815#endif
1816 setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,
1817 (char *)&keepalive, sizeof keepalive);
1818
1819 // Set the traffic class
1820 if ( req->dscp != 0 && !setTrafficClass (fd, family, req->dscp) ) {
1821 MSG_IOevent_IOerror_SET (&statusind.msg, "traffic class");
1822 GetUser()->Deliver (&statusind);
1823 closesocket (fd);
1824 return;
1825 }
1826
1827 // Bind to the local address here, if required */
1828 if ((req->saddr) && (bind(fd, req->saddr, req->salen) == -1)) {
1829 MSG_IOevent_IOerror_SET (&statusind.msg, "bind calling address");
1830 GetUser()->Deliver (&statusind);
1831 closesocket (fd);
1832 return;
1833 }
1834
1835 if ( connect (fd, req->daddr, req->dalen) != 0 ) {
1836 isode_set_errno();
1837 if ( errno == EINPROGRESS || wouldBlock () ) {
1838 // Connect is async, need to wait
1839 _fd = fd;
1840 _state = State_connecting;
1841
1842 // Connected state indicated by socket becoming writable
1843 waitEvent (::Poll::Event_Out);
1844 } else {
1845 // Must be error in connect
1846 MSG_IOevent_IOerror_SET (&statusind.msg, "connect");
1847 GetUser()->Deliver (&statusind);
1848 closesocket (fd);
1849 }
1850
1851 } else {
1852 // Immediate connection
1853
1854 _fd = fd;
1855 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
1856
1857 MSG_IOevent_Connected_SET (&statusind.msg);
1858 GetUser()->Deliver (&statusind);
1859 }
1860}
1861
1862bool Stream::SocketPoll::setTrafficClass (
1863 endpoint_t fd,
1864 int family,
1865 unsigned traffic_class)
1866{
1867 if ( family == PF_INET ) {
1868 // IPv4
1869 // traffic class is in TOS byte, low 2 bits are not used
1870 int tosbyte = traffic_class << 2;
1871#ifdef IP_TOS
1872# ifdef SOL_IP
1873# define TOSLEVEL SOL_IP
1874# else
1875# define TOSLEVEL IPPROTO_IP
1876# endif
1877 return setsockopt (fd, TOSLEVEL, IP_TOS,
1878 (char *)&tosbyte, sizeof tosbyte) == 0;
1879#else
1880 return false;
1881#endif
1882 }
1883
1884 // If IPv6 then already actioned, otherwise ignore
1885 return true;
1886}
1887
1889{
1890 if ( checkUser() ) return;
1891
1892 StatusIndication statusind (this);
1893
1894 LOG_DEBUG (("SocketPoll::actualDeliver (ListenRequest)"));
1895
1896 if ( _state != State_noconnect ) {
1897 MSG_IOevent_NotConnected_SET (&statusind.msg);
1898
1899 GetUser()->Deliver (&statusind);
1900
1901 return;
1902 }
1903
1904 int family;
1905
1906 switch ( req->laddr->sa_family ) {
1907#ifdef AF_UNIX
1908 case AF_UNIX:
1909 family = PF_UNIX;
1910 break;
1911#endif
1912
1913 case AF_INET:
1914 family = PF_INET;
1915 break;
1916
1917#if defined(AF_INET6) && defined(PF_INET6)
1918 case AF_INET6:
1919 family = PF_INET6;
1920 break;
1921#endif
1922
1923 default:
1924 MSG_IOevent_AddrType_SET (&statusind.msg, req->laddr->sa_family);
1925 GetUser()->Deliver (&statusind);
1926 return;
1927 }
1928
1929 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1930
1931 if ( fd == INVALID_ENDPOINT ) {
1932 MSG_IOevent_IOerror_SET (&statusind.msg, "socket");
1933 GetUser()->Deliver (&statusind);
1934 return;
1935 }
1936
1937#if defined(PF_INET6) && defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
1938 if ( family == PF_INET6 ) {
1939 int v6only = 1;
1940
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);
1945 closesocket (fd);
1946 return;
1947 }
1948 }
1949#endif
1950
1951#if !defined(IC_WIN32) && defined(SO_REUSEADDR)
1952 int onoff = 1;
1953
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);
1958 closesocket (fd);
1959 return;
1960 }
1961#endif
1962
1963 if ( bind (fd, req->laddr, req->lalen ) != 0 ) {
1964 MSG_IOevent_IOerror_SET (&statusind.msg, "bind");
1965 GetUser()->Deliver (&statusind);
1966 closesocket (fd);
1967 return;
1968 }
1969
1970#ifdef IC_WIN32
1971 // Windows sockets are inherited by default
1972 if ( SetHandleInformation ((HANDLE)fd,
1973 HANDLE_FLAG_INHERIT, // mask of bits to change
1974 0) == 0 ) {
1975 MSG_IOevent_Inherit_LOG ();
1976 }
1977#elif defined (FD_CLOEXEC)
1978 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1979#endif
1980
1981#ifdef O_NONBLOCK
1982 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1983 MSG_IOevent_IOerror_SET (&statusind.msg, "fcntl");
1984 GetUser()->Deliver (&statusind);
1985 closesocket (fd);
1986 return;
1987 }
1988#elif defined (FIONBIO)
1989 char con = 1;
1990 if ( ioctl (fd, FIONBIO, &con) != 0 ) {
1991 MSG_IOevent_IOerror_SET (&statusind.msg, "ioctl");
1992 GetUser()->Deliver (&statusind);
1993 closesocket (fd);
1994 return;
1995 }
1996#else
1997# error Cannot set socket into non-blocking more
1998#endif
1999
2000 if ( listen (fd, req->backlog ? req->backlog : SOMAXCONN) != 0 ) {
2001 MSG_IOevent_IOerror_SET(&statusind.msg, "listen");
2002 GetUser()->Deliver (&statusind);
2003 closesocket (fd);
2004 return;
2005 }
2006
2007 // Listening
2008 _fd = fd;
2009 _state = State_listening;
2010
2011 // Listen events are 'In' events
2012 waitEvent (::Poll::Event_In);
2013}
2014
2016{
2017 if ( checkUser() ) return;
2018
2019 StatusIndication statusind (this);
2020
2021 LOG_DEBUG (("SocketPoll::actualDeliver (ConnectAccept)"));
2022
2023 if ( _fd == INVALID_ENDPOINT || _state != State_accepting ) {
2024 MSG_IOevent_NotConnected_SET (&statusind.msg);
2025
2026 GetUser()->Deliver (&statusind);
2027
2028 return;
2029 }
2030
2031 // For a socket interface there is nothing to do to accept the connection
2032 _state = GetUser()->Proxy() ? State_need_proxy : State_connected;
2033}
2034
2036{
2037 if ( checkUser() ) return;
2038
2039 StatusIndication statusind (this);
2040
2041 LOG_DEBUG (("SocketPoll::actualDeliver (DisconnectRequest)"));
2042
2043 switch ( _state ) {
2044 case State_need_proxy:
2045 case State_connected:
2046 case State_accepting:
2047 case State_tls:
2048 if ( _fd != INVALID_ENDPOINT )
2049 break;
2050 BOOST_FALLTHROUGH;
2051
2052 default:
2053 MSG_IOevent_NotConnected_SET (&statusind.msg);
2054 GetUser()->Deliver (&statusind);
2055 return;
2056 }
2057
2058 if ( _state == State_tls ) {
2059 _tlsstate = TLS_close;
2060
2061 doTLS();
2062
2063 } else {
2064 // Close up connection, etc.
2065
2066 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
2067 GetUser()->Deliver (&statusind);
2068
2069 tidy ();
2070 }
2071}
2072
2074{
2075 if ( checkUser() ) return;
2076
2077 StatusIndication statusind (this);
2078
2079 LOG_DEBUG (("SocketPoll::actualDeliver (DataRequest) state=%d _wlen=%ld",
2080 _state, (long)_wlen));
2081
2082 switch ( _state ) {
2083 case State_need_proxy:
2084 case State_connected:
2085 case State_tls:
2086 if ( _fd != INVALID_ENDPOINT )
2087 break;
2088 BOOST_FALLTHROUGH;
2089
2090 default:
2091 MSG_IOevent_NotConnected_SET (&statusind.msg);
2092 GetUser()->Deliver (&statusind);
2093 return;
2094 }
2095
2096 // Note: should not attempt to write zero bytes
2097 if ( req->buf == 0 || req->len == 0 ) {
2098 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
2099 req->buf == NULL ?
2100 "buffer pointer" :
2101 "zero length");
2102
2103 GetUser()->Deliver (&statusind);
2104
2105 return;
2106 }
2107
2108 if ( _wlen != 0 ) {
2109 ReleaseBuf release;
2110
2111 release.buf = req->buf;
2112 release.len = -1;
2113
2114 GetUser()->Deliver (&release);
2115
2116 MSG_IOevent_DupWrite_SET (&statusind.msg);
2117
2118 GetUser()->Deliver (&statusind);
2119
2120 return;
2121 }
2122
2123 _wbuf = _wptr = req->buf;
2124 _wlen = req->len;
2125
2126 if ( _state == State_connected || _state == State_need_proxy ) {
2127 if (_state == State_need_proxy) {
2128 LOG_DEBUG (("Need proxy state seen when writing"));
2129 }
2130 if ( !doWrite () ) {
2131 // Write blocked, tell poller we want to know when can write
2132 waitEvent (::Poll::Event_Out);
2133 }
2134
2135 } else {
2136 doTLS();
2137 }
2138}
2139
2141{
2142 if ( checkUser() ) return;
2143
2144 DataIndication dataind;
2145 StatusIndication statusind (this);
2146
2147 LOG_DEBUG (("SocketPoll::actualDeliver (ReadRequest)"));
2148
2149 switch ( _state ) {
2150 case State_need_proxy:
2151 case State_connected:
2152 case State_tls:
2153 if ( _fd != INVALID_ENDPOINT )
2154 break;
2155 BOOST_FALLTHROUGH;
2156
2157 default:
2158 MSG_IOevent_NotConnected_SET (&statusind.msg);
2159 GetUser()->Deliver (&statusind);
2160 return;
2161 }
2162
2163 if ( req->buf == 0 || req->len == 0 ) {
2164 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
2165 req->buf == NULL ?
2166 "buffer pointer" :
2167 "zero length");
2168
2169 GetUser()->Deliver (&statusind);
2170
2171 return;
2172 }
2173
2174 if ( _rlen != 0 ) {
2175 dataind.buf = req->buf;
2176 dataind.len = -1;
2177
2178 GetUser()->Deliver (&dataind);
2179
2180 MSG_IOevent_DupRead_SET (&statusind.msg);
2181
2182 GetUser()->Deliver (&statusind);
2183
2184 return;
2185 }
2186
2187 _rbuf = _rptr = req->buf;
2188 _rlen = req->len;
2189 _rfill = req->fill;
2190
2191 LOG_DEBUG (("ReadRequest: _rbuf=%p _rlen=%d _rfill=%d",
2192 _rbuf, (int)_rlen, _rfill));
2193
2194 if ( _state == State_connected || _state == State_need_proxy ) {
2195 // If the previous read filled the provided buffer, then
2196 // we attempt a read at this point. There may be more data
2197 // already buffered in the OS
2198
2199 if ( _rfull
2200 && ((_state == State_connected && doRead () )
2201 || (_state == State_need_proxy && doProxy() )) )
2202 return;
2203
2204 // tell poller we are interested in read events
2205 waitEvent (::Poll::Event_In);
2206
2207 } else {
2208 doTLS();
2209 }
2210}
2211
2213{
2214 if ( checkUser() ) return;
2215
2216 LOG_DEBUG (("SocketPoll::actualDeliver (StartTLS)"));
2217
2218 StatusIndication statusind (this);
2219
2220 switch ( _state ) {
2221 case State_tls:
2222 MSG_IOevent_SSLalready_SET (&statusind.msg);
2223 GetUser()->Deliver (&statusind);
2224 return;
2225
2226 case State_connected:
2227 if ( _fd != INVALID_ENDPOINT )
2228 break;
2229 BOOST_FALLTHROUGH;
2230
2231 default:
2232 MSG_IOevent_NotConnected_SET (&statusind.msg);
2233 GetUser()->Deliver (&statusind);
2234 return;
2235 }
2236
2237 // Only check hostname of server
2238 _hostname = req->client ? req->hostname : 0;
2239
2240 SSLTLS::OpenSSLContext *sslctx =
2241 dynamic_cast<SSLTLS::OpenSSLContext *>(req->context);
2242
2243 _ssl = sslctx ? sslctx->GetSSL(_choice) : NULL;
2244 if (!_ssl) {
2245 MSG_IOevent_SSLerror_SET (&statusind.msg, "SSL_new", "this returned NULL. No ID configured?");
2246 GetUser()->Deliver (&statusind);
2247 return;
2248 }
2249
2250 // Check for any OpenSSL error set during previous use of this thread
2251 int err = SSL_get_error(_ssl, 0);
2252 if (err != SSL_ERROR_NONE) {
2253 // Report but clear and continue
2254 LOG_DEBUG (("SocketPoll::actualDeliver(StartTLS) - SSL error code %d", err));
2255 ERR_clear_error();
2256 }
2257
2258 BIO *bio = BIO_new_socket (_fd, TRUE);
2259
2260 SSL_set_bio(_ssl, bio, bio);
2261
2262 if ( req->client )
2263 SSL_set_connect_state (_ssl);
2264 else
2265 SSL_set_accept_state (_ssl);
2266
2267 _state = State_tls;
2268 _tlsstate = TLS_handshake;
2269
2270 doTLS();
2271}
2272
2274{
2275 if ( checkUser() ) return;
2276
2277 LOG_DEBUG (("SocketPoll::actualDeliver (StreamControl)"));
2278
2279 StatusIndication statusind (this);
2280
2281 if ( _fd == INVALID_ENDPOINT ) {
2282 MSG_IOevent_NotConnected_SET (&statusind.msg);
2283 GetUser()->Deliver (&statusind);
2284 return;
2285 }
2286
2287 int level;
2288 int name;
2289
2290 switch ( option->option ) {
2291#if defined(TCP_NODELAY)
2292 case StreamControlNoDelay:
2293 level = IPPROTO_TCP;
2294 name = TCP_NODELAY;
2295 break;
2296#endif
2297
2299 level = SOL_SOCKET;
2300 name = SO_KEEPALIVE;
2301 break;
2302
2303#if defined(IP_TOS)
2304 case StreamControlTOS:
2305#ifdef SOL_IP
2306 level = SOL_IP;
2307#else
2308 level = IPPROTO_IP;
2309#endif
2310 name = IP_TOS;
2311 break;
2312#endif
2313
2314 default:
2315 MSG_IOevent_UnknownStreamOpt_SET (&statusind.msg, option->option);
2316 GetUser()->Deliver (&statusind);
2317 return;
2318 }
2319
2320 int rc = setsockopt (_fd, level, name, (char *)&option->value, sizeof option->value);
2321 if ( rc != 0 ) {
2322 MSG_IOevent_IOerror_SET (&statusind.msg, "setsockopt");
2323 GetUser()->Deliver (&statusind);
2324 tidy ();
2325 }
2326}
2327
2328
2329Stream::Provider *Stream::CreateSocketPollProvider ()
2330{
2331 // In a single-threaded environment COULD create a SocketPoll
2332 return new Stream::SyncSocketPoll;
2333}
tls_verify_client_choice
Values for choosing client verification.
Definition SSLconfig.h:51
Poll provider interface.
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.
Definition Syncmsg.h:30
void Init(C *rcvr)
Set the target.
Definition Syncmsg.h:48
Template class for protecting an object.
Definition Syncmsg.h:168
void msgDeliver(M *msg)
template function for delivering message of given type to receiver
Definition Syncmsg.h:290
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.
Accept a connection.
Connection indication.
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.
Request a connection.
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.
Data read from provider.
ssize_t len
Address of data.
Information for sending data.
size_t len
Pointer to data to be transferred.
Disconnect the stream.
Push an external endpoint into the provider.
bool listen
The network endpoint from some external source.
Sets length function.
socklen_t lalen
Listen address.
int backlog
Length of listen address.
Data read from provider.
bool fill
Length of data read.
size_t len
Address of data.
Release buffer.
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.

All rights reserved © 2002 - 2024 Isode Ltd.