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
23#include "../include/Syncmsg.h"
24
25#include <isode/messages/base.h>
26#include <isode/base/crypto.h>
27
28// Should be set to the size of the longest sockaddr
29// There is no easy and portable way to define this.
30// The size here is probably generous.
31#define MAXSOCKADDRLEN 1024
32
33namespace Stream {
34
36 // This is the core interface which we wrap to get the thread
37 // synchronization. In a non-thread environment, this could be
38 // used directly, which is more efficient.
39
40 class SocketPoll : public Provider, public ::Poll::User {
41 private:
42 ::Poll::Provider *_poller;
43 enum State {
44 State_noconnect,
45 State_listening,
46 State_connecting,
47 State_accepting,
48 State_connected,
49 State_tls
50 } _state;
51
52 // Reader stuff
53 char * _rbuf;
54 char * _rptr;
55 size_t _rlen;
56 bool _rfill;
57 bool _rfull;
58
59 // Writer stuff
60 const char * _wbuf;
61 const char * _wptr;
62 size_t _wlen;
63
64 // Addresses for ConnectionIndication
65 socklen_t _clen;
66 struct sockaddr_storage _caddr;
67 socklen_t _llen;
68 struct sockaddr_storage _laddr;
69
70 SSL * _ssl;
71 const char * _hostname;
72
74
76 unsigned _emfile;
77
78 enum TLSstate {
79 TLS_idle,
80 TLS_handshake,
81 TLS_write,
82 TLS_close
83 } _tlsstate;
84
85 bool _noshut;
86
88 inline bool checkUser () {
89 if ( GetUser() == 0 ) {
90 MSG_IOevent_MissingUser_LOG ();
91 return true;
92 }
93 return false;
94 }
95
97 inline bool wouldBlock () {
98 return ( errno == EWOULDBLOCK || errno == EAGAIN );
99 }
100
102 inline void waitEvent (unsigned events);
103
105 // This routine is responsible for signalling the User
106 inline bool doRead ();
107
109 // This routine is responsible for signalling the User
110 inline bool doWrite ();
111
113 inline void doAccept ();
114
116 void doTLS ();
117
119 inline int doTLSread();
120
122 // returns true if worked, false on SSL error
123 inline int doTLSwrite();
124
126 // returns true if worked, false on SSL error
127 inline int doTLShandshake();
128
130 // returns true if worked, false on SSL error
131 inline int doTLSshutdown();
132
134 inline bool setTrafficClass (
135 endpoint_t fd,
136 int family,
137 unsigned traffic_class);
138
139 protected:
140 virtual ~SocketPoll() {
141 tidy ();
142 }
143
144 public:
145 SocketPoll () :
146 _poller (0),
147 _state (State_noconnect),
148 _rlen (0),
149 _rfill (false),
150 _rfull (false),
151 _wlen (0),
152 _ssl (0),
153 _hostname (0),
154 _emfile (0),
155 _noshut (false)
156 {
157 _event.Init (this);
158 _timer.Init (this);
159 }
160
162 virtual void Die () {
163 delete this;
164 }
165
167 inline void tidy () {
168 SetUser (0);
169
170 if ( _ssl != 0 ) {
171 if ( _poller != 0 ) {
172 _poller->Deregister (this);
173 _poller = 0;
174 }
175
176 // This closes the socket
177 int err = SSL_get_error(_ssl, 0);
178 if (err != SSL_ERROR_NONE) {
179 // Report but clear and continue
180 LOG_DEBUG (("SocketPoll::tidy() - SSL error (%d)", err));
181 ERR_clear_error();
182 }
183 SSL_free (_ssl);
184 _ssl = 0;
185
186 _fd = INVALID_ENDPOINT;
187 _event.Cancel ();
188
189 } else if ( _fd != INVALID_ENDPOINT ) {
190 if ( _poller != 0 ) {
191 _poller->Deregister (this);
192 _poller = 0;
193 }
194
195 // This seems to be the way to close sockets cleanly
196 // on Windows. If you use SHUT_RDWR (aka SH_BOTH) the
197 // remote end can be reset.
198 if ( !_noshut )
199 shutdown (_fd, SHUT_WR);
200
201 closesocket (_fd);
202 _fd = INVALID_ENDPOINT;
203
204 _event.Cancel ();
205 }
206
207 _rbuf = _rptr = 0;
208 _rlen = 0;
209 _rfull = false;
210
211 _state = State_noconnect;
212 }
213
215 // If requested make sure endpoint can be inherited
216 virtual endpoint_t GetEndpoint (bool inheriting) {
217 if ( inheriting ) {
218 _noshut = true;
219
220#ifdef IC_WIN32
221 if ( SetHandleInformation ((HANDLE)_fd,
222 HANDLE_FLAG_INHERIT,
223 HANDLE_FLAG_INHERIT) == 0 ) {
224 MSG_IOevent_Inherit_LOG();
225 }
226
227#elif defined (FD_CLOEXEC)
228 int flags = fcntl (_fd, F_GETFD, 0);
229
230 if ( flags >= 0 ) {
231 flags &= ~FD_CLOEXEC;
232 if ( fcntl (_fd, F_SETFD, flags) != 0 ) {
233 MSG_IOevent_Inherit_LOG ();
234 }
235 }
236#endif
237 }
238 return _fd;
239 }
240
242 virtual unsigned Events () {
243 return _uevents;
244 }
245
247 virtual int GetLocalAddress (struct sockaddr *laddr,
248 socklen_t *lalenp,
249 MSGstruct *msp) {
250
251 if ( _fd == INVALID_ENDPOINT ) {
252 MSG_IOevent_NotConnected_SET (msp);
253 return MSG_IOevent_NotConnected;
254 }
255
256#ifdef GETSOCKNAME_NEEDS_INTP
257 int lalen;
258#else
259 socklen_t lalen;
260#endif
261 lalen = *lalenp;
262 if ( getsockname (_fd, laddr, &lalen) != 0 ) {
263 *lalenp = lalen;
264 MSG_IOevent_IOerror_SET (msp, "getsockname");
265 return MSG_IOevent_IOerror;
266 }
267
268 // In case encapsulated IPv4 address
269 *lalenp = convert2ipv4 (laddr, lalen);
270 return 0;
271 }
272
274 virtual int GetPeerAddress (struct sockaddr *laddr,
275 socklen_t *lalenp,
276 MSGstruct *msp) {
277
278 if ( _fd == INVALID_ENDPOINT ) {
279 MSG_IOevent_NotConnected_SET (msp);
280 return MSG_IOevent_NotConnected;
281 }
282
283#ifdef GETPEERNAME_NEEDS_INTP
284 int lalen;
285#else
286 socklen_t lalen;
287#endif
288 lalen = *lalenp;
289 if ( getpeername (_fd, laddr, &lalen) != 0 ) {
290 *lalenp = lalen;
291 MSG_IOevent_IOerror_SET (msp, "getpeername");
292 return MSG_IOevent_IOerror;
293 }
294
295 // In case encapsulated IPv4 address
296 *lalenp = convert2ipv4 (laddr, lalen);
297 return 0;
298 }
299
301 virtual TLS_CipherSuite GetCipherSuite () {
302 if ( _state != State_tls || _ssl == 0 )
303 return TLS_NULL_WITH_NULL_NULL;
304
305 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
306 return SSLTLS::cipher_id(cipher);
307 }
308
310 virtual X509* GetPeerCertificate () {
311 if ( _state != State_tls || _ssl == 0 )
312 return 0;
313
314 return SSL_get_peer_certificate(_ssl);
315 }
316
318 // This is virtual so that each subclass can override
319 virtual SocketPoll *Clone () = 0;
320
321 // Since the interface will be protected,
322 // We need specific functions for each of the deliver cases
323
325 void actualDeliver (time_t *msg);
326
328 void actualDeliver (::Poll::pollmsg *msg);
329
330 // Interface to stream user
332 void actualDeliver (External *ext);
333
335 void actualDeliver (ConnectRequest *req);
336
338 void actualDeliver (ListenRequest *req);
339
342
345
347 void actualDeliver (DataRequest *req);
348
350 void actualDeliver (ReadRequest *req);
351
353 void actualDeliver (StartTLS *req);
354
356 void actualDeliver (StreamControl *option);
357
359 virtual void Deliver (time_t *msg) {
360 actualDeliver (msg);
361 }
362
363 // Interface from poll provider
364
366 virtual void Deliver (::Poll::pollmsg *msg) {
367 actualDeliver (msg);
368 }
369
370 // Interface to stream user
372 virtual void Deliver (External *ext) {
373 actualDeliver (ext);
374 }
375
377 virtual void Deliver (ConnectRequest *req) {
378 actualDeliver (req);
379 }
380
382 virtual void Deliver (ListenRequest *req) {
383 actualDeliver (req);
384 }
385
387 virtual void Deliver (ConnectAccept *req) {
388 actualDeliver (req);
389 }
390
392 virtual void Deliver (DisconnectRequest *req) {
393 actualDeliver (req);
394 }
395
397 virtual void Deliver (DataRequest *req) {
398 actualDeliver (req);
399 }
400
402 virtual void Deliver (ReadRequest *req) {
403 actualDeliver (req);
404 }
405
407 virtual void Deliver (StartTLS *req) {
408 actualDeliver (req);
409 }
410
412 virtual void Deliver (StreamControl *option) {
413 actualDeliver (option);
414 }
415
417 virtual void Deliver (LengthFnxRequest *) {
418 // Don't bother to synchronize this
419 }
420 };
421
423 class SyncSocketPoll : public Syncmsgobj<SocketPoll> {
424 protected:
425 virtual ~SyncSocketPoll () {
426 // Need to call tidy() here to ensure stuff is cleared up
427 // while this actual object exists.
428 tidy();
429 }
430
431 public:
432 // for Deliver(Stream::LengthFnxRequest*)
434
436 virtual SocketPoll *Clone () {
437 return new SyncSocketPoll ();
438 }
439
441 virtual void Die () {
442 dieAux ();
443 }
444
446 virtual void Deliver (time_t *msg) {
447 actualDeliver (msg);
448 }
449
451 virtual void Deliver (::Poll::pollmsg *msg) {
452 msgDeliver (msg);
453 }
454
455 // Interface to stream user
457 virtual void Deliver (External *ext) {
458 msgDeliver (ext);
459 }
460
462 virtual void Deliver (ConnectRequest *req) {
463 msgDeliver (req);
464 }
465
467 virtual void Deliver (ListenRequest *req) {
468 msgDeliver (req);
469 }
470
472 virtual void Deliver (ConnectAccept *req) {
473 msgDeliver (req);
474 }
475
477 virtual void Deliver (DisconnectRequest *req) {
478 msgDeliver (req);
479 }
480
482 virtual void Deliver (DataRequest *req) {
483 msgDeliver (req);
484 }
485
487 virtual void Deliver (ReadRequest *req) {
488 msgDeliver (req);
489 }
490
492 virtual void Deliver (StartTLS *req) {
493 msgDeliver (req);
494 }
495
497 virtual void Deliver (StreamControl *option) {
498 msgDeliver (option);
499 }
500 };
501}
502
503// SocketPoll implementation
504
505inline void Stream::SocketPoll::waitEvent (unsigned events)
506{
507 StatusIndication statusind (this);
508
509 if ( _fd == INVALID_ENDPOINT )
510 return;
511
512 if ( _poller == 0 ) {
514
515 if ( _poller == 0 ) {
516 MSG_IOevent_NoPollProvider_SET (&statusind.msg);
517 GetUser()->Deliver (&statusind);
518 tidy ();
519 return;
520 }
521
522 int rc = _poller->Register (this);
523
524 if ( rc != 0 ) {
525 MSG_IOevent_PollRegister_SET (&statusind.msg, rc);
526 GetUser()->Deliver (&statusind);
527 tidy ();
528 return;
529 }
530 }
531
532 _uevents |= events;
533
534 // If have events which the poller is not already listening for,
535 // tell it to listen
536 if ( _uevents & ~_pevents )
537 _poller->Control (this);
538}
539
540bool Stream::SocketPoll::doWrite ()
541{
542 ssize_t remain = (ssize_t)_wlen - (_wptr - _wbuf);
543 ssize_t tosend = remain;
544 ssize_t nbytes;
545
546 LOG_DEBUG (("SocketPoll::doWrite() - send %ld", (long)tosend));
547
548 while (1) {
549 nbytes = send (_fd, _wptr, tosend, 0);
550
551 if ( nbytes <= 0 ) {
552 StatusIndication statusind (this);
553
554 if ( nbytes == 0 ) {
555 // EOF
556 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
557 break;
558 } else {
559 isode_set_errno();
560 // If error is that read would block, then just return
561 // Caller should ensure that poller knows we want to
562 // know when readable.
563 if ( wouldBlock () )
564 return false;
565#ifdef IC_WIN32
566 // On Windows we may get WSAENOBUFS (converted to ENOBUFS in isode_set_errno)
567 // if the data we are attempting to send is 'too big'
568 if (errno == ENOBUFS) {
569 // Try and send half as much data....
570 tosend = tosend / 2;
571 LOG_DEBUG (("SocketPoll::doWrite() - retry send with %d", tosend));
572 }
573
574 if ((tosend == 0) || (errno != ENOBUFS)) {
575 // Error!
576 MSG_IOevent_IOerror_SET (&statusind.msg, "send");
577 break;
578 }
579 continue;
580#else
581 // Error
582 MSG_IOevent_IOerror_SET (&statusind.msg, "send");
583 break;
584#endif
585 }
586
587 GetUser()->Deliver (&statusind);
588
589 tidy ();
590
591 return true;
592 } else {
593 break;
594 }
595 }
596
597 _wptr += nbytes;
598 remain -= nbytes;
599
600 if ( remain == 0 ) {
601 ReleaseBuf release;
602
603 release.buf = _wbuf;
604 release.len = _wptr - _wbuf;
605
606 _wbuf = _wptr = 0;
607 _wlen = 0;
608
609 GetUser()->Deliver (&release);
610
611 return true;
612 }
613
614 // Presume that the reason the write was incomplete is that
615 // the next attempt would block
616 return false;
617}
618
619bool Stream::SocketPoll::doRead ()
620{
621 ssize_t remain = (ssize_t)_rlen - (_rptr - _rbuf);
622
623 LOG_DEBUG (("doRead: _rlen=%d remain=%d", (int)_rlen, (int)remain));
624
625 ssize_t nbytes = recv (_fd, _rptr, remain, 0);
626
627 LOG_DEBUG (("doRead: recv -> %d", (int)nbytes));
628
629 if ( nbytes <= 0 ) {
630 StatusIndication statusind (this);
631
632 if ( nbytes == 0 ) {
633 // EOF
634 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
635 } else {
636 isode_set_errno();
637 // If error is that read would block, then just return
638 // Caller should ensure that poller knows we want to
639 // know when readable.
640 if ( wouldBlock () )
641 return false;
642
643 // Error
644 MSG_IOevent_IOerror_SET (&statusind.msg, "recv");
645 }
646
647 GetUser()->Deliver (&statusind);
648
649 tidy ();
650
651 return true;
652 }
653
654 // The read filled the buffer - there may be more queued
655 if ( nbytes == remain )
656 _rfull = true;
657
658 _rptr += nbytes;
659 remain -= nbytes;
660
661 LOG_DEBUG (("doRread: remain=%d _rfill=%d", (int)remain, _rfill));
662
663 // If not filling buffer or the buffer is full, send
664 // data indication
665 if ( !_rfill || remain == 0 ) {
666 DataIndication dataind;
667
668 dataind.buf = _rbuf;
669 dataind.len = _rptr - _rbuf;
670
671 _rbuf = _rptr = 0;
672 _rlen = 0;
673
674 GetUser()->Deliver (&dataind);
675
676 return true;
677 }
678
679 // Need to read some more
680 return false;
681}
682
683void Stream::SocketPoll::doAccept ()
684{
685 StatusIndication statusind (this);
686 char abuf[MAXSOCKADDRLEN];
687#ifdef ACCEPT_NEEDS_INTP
688 int alen;
689#else
690 socklen_t alen;
691#endif
692 alen = sizeof abuf;
693
694 endpoint_t newfd = accept (_fd, (struct sockaddr *)abuf, &alen);
695 if (INVALID_ENDPOINT == newfd) {
696 isode_set_errno();
697 // Note: need to distinguish the serious cases where accept should
698 // not have been called, and failures of the individual accept.
699 switch ( errno ) {
700 default:
701 // Note: could get repeating errors here. E.g. if at limit of
702 // number of open files for the process or system.
703 MSG_IOevent_AcceptError_SET (&statusind.msg);
704 MSGappendsyserror (&statusind.msg);
705 GetUser()->Deliver (&statusind);
706 break;
707
708 case EMFILE:
709 // No point in trying again immediately, as it would spin
710 // Notify user and wait for a while before trying again
711 MSG_IOevent_AcceptError_SET (&statusind.msg);
712 MSGappendsyserror (&statusind.msg);
713 GetUser()->Deliver (&statusind);
714 {
715 time_t dummy = 0;
716 _emfile++;
717 if ( _emfile > 100 ) _emfile = 100;
718
719 _timer.Sendms (100*_emfile, dummy); // 100 ms times # errors
720 }
721 return;
722
723 case EBADF:
724 case EINVAL:
725#ifdef ENOTSOCK
726 case ENOTSOCK:
727#endif
728#ifdef EOPNOTSUPP
729 case EOPNOTSUPP:
730#endif
731#ifdef EFAULT
732 case EFAULT:
733#endif
734 // A severe error, abandon listen
735 MSG_IOevent_IOerror_SET (&statusind.msg, "accept");
736 GetUser()->Deliver (&statusind);
737 tidy ();
738 return;
739
740#ifdef EINTR
741 case EINTR:
742#endif
743#ifdef EAGAIN
744 case EAGAIN:
745#endif
746#if defined(EWOULDBLOCK)
747# if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
748 case EWOULDBLOCK:
749# endif
750#endif
751 // False alarm
752 break;
753 }
754 } else {
755 // Have new connection from peer
756#ifdef IC_WIN32
757 // Windows sockets are inherited by default
758 if ( SetHandleInformation(
759 (HANDLE)newfd,
760 HANDLE_FLAG_INHERIT, // mask of bits to change
761 0) == 0 ) {
762 MSG_IOevent_Inherit_LOG();
763 }
764#elif defined (FD_CLOEXEC)
765 (void) fcntl(newfd, F_SETFD, FD_CLOEXEC);
766#endif
767
768 bool do_setsockopt = true;
769#ifdef O_NONBLOCK
770 if ( fcntl(newfd, F_SETFL, O_NONBLOCK) != 0 ) {
771 closesocket(newfd);
772 MSG_IOevent_IoctlError_SET(&statusind.msg);
773 MSGappendsyserror(&statusind.msg);
774 GetUser()->Deliver(&statusind);
775 do_setsockopt = false;
776 }
777#elif defined(FIONBIO)
778 char onoff = 1;
779 if ( ioctl(newfd, FIONBIO, &onoff) != 0 ) {
780 closesocket(newfd);
781 MSG_IOevent_IoctlError_SET(&statusind.msg);
782 MSGappendsyserror(&statusind.msg);
783 GetUser()->Deliver(&statusind);
784 do_setsockopt = false;
785 }
786#else
787#error Cannot set socket into non-blocking more
788#endif
789 if (do_setsockopt) {
790#ifdef TCP_NODELAY
791 // Always set this on by default
792#ifdef IC_WIN32
793 char nodelay = 1;
794#else
795 int nodelay = 1;
796#endif
797 // But ignore failure
798 setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof nodelay);
799#endif
800 // Always set keepalives (and ignore failure)
801#ifdef IC_WIN32
802 char keepalive = 1;
803#else
804 int keepalive = 1;
805#endif
806 setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepalive, sizeof keepalive);
807
809 Stream::SocketPoll * newprov = Clone();
810
811 connind.listener = this;
812 connind.newprovider = newprov;
813
814 newprov->_fd = newfd;
815 newprov->_state = State_accepting;
816
817 memcpy(&newprov->_caddr, abuf, alen);
818 newprov->_clen = alen;
819
820 connind.saddr = reinterpret_cast<struct sockaddr *>(&newprov->_caddr);
821 connind.salen = convert2ipv4(reinterpret_cast<struct sockaddr *>(&newprov->_caddr), alen);
822
823#ifdef GETSOCKNAME_NEEDS_INTP
824 int llen;
825#else
826 socklen_t llen;
827#endif
828 llen = sizeof newprov->_laddr;
829 newprov->_llen = sizeof newprov->_laddr;
830
831 getsockname(newfd, reinterpret_cast<struct sockaddr *>(&newprov->_laddr), &llen);
832
833 newprov->_llen = llen;
834
835 connind.laddr = reinterpret_cast<struct sockaddr *>(&newprov->_laddr);
836 connind.lalen = newprov->_llen;
837
838 GetUser()->Deliver(&connind);
839 }
840 }
841
842 // Accept did not fail or have EMFILE
843 _emfile = 0;
844
845 // Go back for more
846 waitEvent (::Poll::Event_In);
847}
848
849
850int Stream::SocketPoll::doTLSread ()
851{
852 int remain = (int)_rlen - (_rptr - _rbuf);
853
854 LOG_DEBUG (("doTLSread: _rlen=%d remain=%d", (int)_rlen, (int)remain));
855
856 int nbytes = SSL_read (_ssl, _rptr, remain);
857
858 LOG_DEBUG (("doTLSread: SSL_read -> %d", nbytes));
859
860 // SSL errors handled by caller
861 if ( nbytes < 0 )
862 return nbytes;
863
864 if ( nbytes == 0 ) {
865 StatusIndication statusind (this);
866
867 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
868
869 GetUser()->Deliver (&statusind);
870
871 _tlsstate = TLS_idle;
872
873 tidy ();
874 return 1; // Fudge to stop error handling
875 }
876
877 // The read filled the buffer - there may be more queued
878 if ( nbytes == remain )
879 _rfull = true;
880
881 _rptr += nbytes;
882 remain -= nbytes;
883
884 LOG_DEBUG (("doRread: remain=%d _rfill=%d", (int)remain, _rfill));
885
886 // If not filling buffer or the buffer is full, send
887 // data indication
888 if ( !_rfill || remain == 0 ) {
889 DataIndication dataind;
890
891 dataind.buf = _rbuf;
892 dataind.len = _rptr - _rbuf;
893
894 _rbuf = _rptr = 0;
895 _rlen = 0;
896
897 _tlsstate = TLS_idle;
898
899 GetUser()->Deliver (&dataind);
900 }
901
902 return nbytes;
903}
904
905int Stream::SocketPoll::doTLSwrite ()
906{
907 int remain = (int)_wlen - (_wptr - _wbuf);
908
909 int nbytes = SSL_write (_ssl, _wptr, remain);
910
911 // Errors handled in caller
912 if ( nbytes <= 0 )
913 return nbytes;
914
915 _wptr += nbytes;
916 remain -= nbytes;
917
918 if ( remain == 0 ) {
919 ReleaseBuf release;
920
921 release.buf = _wbuf;
922 release.len = _wptr - _wbuf;
923
924 _wbuf = _wptr = 0;
925 _wlen = 0;
926
927 GetUser()->Deliver (&release);
928
929 _tlsstate = TLS_idle;
930 }
931
932 return nbytes;
933}
934
935int Stream::SocketPoll::doTLShandshake ()
936{
937 int rc = SSL_do_handshake (_ssl);
938
939 if ( rc < 0 )
940 return rc;
941
942 StatusIndication statusind (this);
943
944 if ( rc == 0 ) {
945 _tlsstate = TLS_idle;
946
947 return 0;
948 }
949
950 _tlsstate = TLS_idle;
951
952 const char *version = SSL_get_version(_ssl);
953
954 const SSL_CIPHER *cipher = SSL_get_current_cipher(_ssl);
955 TLS_CipherSuite cs = SSLTLS::cipher_id(cipher);
956 int strength = SSL_CIPHER_get_bits(cipher, NULL);
957
958 X509 *peer = SSL_get_peer_certificate(_ssl);
959
960 bool closing = true;
961
962 MSGstruct submsg;
963
964 if ( !peer ) {
965 if ( _choice == SSLTLS::tls_verify_require ) {
966 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
967 MSG_IOevent_SSLnocert_SET (&submsg);
968 MSGappend (&statusind.msg, &submsg);
969
970 } else {
971 MSG_IOevent_SSLOK_SET (&statusind.msg,
972 version, cs, strength);
973
974 closing = false;
975 }
976
977 } else if ( _choice == SSLTLS::tls_verify_none ) {
978 MSG_IOevent_SSLOK_SET (&statusind.msg,
979 version, cs, strength);
980
981 closing = false;
982
983 } else {
984
985 X509_NAME *subject_name = X509_get_subject_name(peer);
986
987 long result = SSL_get_verify_result(_ssl);
988 char *peername = X509_NAME_to_text (subject_name);
989
990 switch (result) {
991 case X509_V_OK:
992 closing = false;
993 MSG_IOevent_SSLverified_SET (&statusind.msg,
994 version, cs, strength,
995 peername);
996 break;
997
998 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
999 MSG_IOevent_SSLnoissuercert_SET (&submsg);
1000 break;
1001 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1002 MSG_IOevent_SSLcertdecryptfailed_SET (&submsg);
1003 break;
1004 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1005 MSG_IOevent_SSLcertsignature_SET (&submsg);
1006 break;
1007 case X509_V_ERR_CERT_NOT_YET_VALID:
1008 MSG_IOevent_SSLcertnotyetvalid_SET (&submsg);
1009 break;
1010 case X509_V_ERR_CERT_HAS_EXPIRED:
1011 MSG_IOevent_SSLcertexpired_SET (&submsg);
1012 break;
1013 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1014 MSG_IOevent_SSLcertnotbefore_SET (&submsg);
1015 break;
1016 case X509_V_ERR_OUT_OF_MEM:
1017 MSG_Base_Nomem_SET (&submsg, 0);
1018 break;
1019 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1020 MSG_IOevent_SSLselfsigned_SET (&submsg);
1021 break;
1022 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1023 MSG_IOevent_SSLlocalissuer_SET (&submsg);
1024 break;
1025 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1026 MSG_IOevent_SSLleafsignature_SET (&submsg);
1027 break;
1028 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1029 MSG_IOevent_SSLchaintoolong_SET (&submsg);
1030 break;
1031 case X509_V_ERR_INVALID_CA:
1032 MSG_IOevent_SSLinvalidCA_SET (&submsg);
1033 break;
1034 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1035 MSG_IOevent_SSLpathlength_SET (&submsg);
1036 break;
1037 case X509_V_ERR_INVALID_PURPOSE:
1038 MSG_IOevent_SSLinvalidpurpose_SET (&submsg);
1039 break;
1040 case X509_V_ERR_CERT_UNTRUSTED:
1041 MSG_IOevent_SSLuntrusted_SET (&submsg);
1042 break;
1043 case X509_V_ERR_CERT_REJECTED:
1044 MSG_IOevent_SSLrejected_SET (&submsg);
1045 break;
1046 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
1047 MSG_IOevent_SSLsubjectissuer_SET (&submsg);
1048 break;
1049 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
1050 MSG_IOevent_SSLserialmismatch_SET (&submsg);
1051 break;
1052 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
1053 MSG_IOevent_SSLkeyusage_SET (&submsg);
1054 break;
1055 default:
1056 MSG_IOevent_SSLunknown_SET (&submsg, result);
1057 break;
1058 }
1059
1060 if ( closing ) {
1061 MSG_IOevent_SSLnotverified_SET (&statusind.msg);
1062 MSGappend (&statusind.msg, &submsg);
1063 }
1064
1065 if (x509_acceptable_name(subject_name) != OK) {
1066 closing = true;
1067 MSG_IOevent_SSLnul_in_subject_LOG(peername);
1068 }
1069
1070 if ( peername != 0 )
1071 free (peername);
1072 }
1073
1074 if ( peer ) {
1075 if (!closing && _hostname &&
1076 SSLTLS::CheckHostname (peer, _hostname, &statusind.msg) != OK ) {
1077 closing = true;
1078 }
1079
1080 X509_free(peer);
1081 }
1082
1083 _tlsstate = TLS_idle;
1084
1085 GetUser()->Deliver (&statusind);
1086
1087 if ( closing )
1088 tidy ();
1089
1090 return rc;
1091}
1092
1093int Stream::SocketPoll::doTLSshutdown ()
1094{
1095 int rc = SSL_shutdown (_ssl);
1096
1097 if ( rc <= 0 ) {
1098 if (rc == 0) {
1099 LOG_DEBUG (("SocketPoll::doTLSshutdown() - shutdown in progress"));
1100 } else {
1101 int err = SSL_get_error(_ssl, rc);
1102 LOG_DEBUG (("SocketPoll::doTLSshutdown() - SSL error (%d)", err));
1103 }
1104 return rc;
1105 }
1106
1107 // Shutdown successful, tell user
1108
1109 StatusIndication statusind (this);
1110 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1111 GetUser()->Deliver (&statusind);
1112
1113 // Close up connection, etc.
1114 _tlsstate = TLS_idle;
1115 tidy ();
1116
1117 return rc;
1118}
1119
1120void Stream::SocketPoll::doTLS ()
1121{
1122 for (;;) {
1123 int rc = 0;
1124
1125 // If there is no SSL, then the connection is being closed down
1126 if ( _ssl == 0 )
1127 return;
1128
1129 switch ( _tlsstate ) {
1130 case TLS_idle:
1131 if ( _wlen != 0 ) {
1132 _tlsstate = TLS_write;
1133 rc = doTLSwrite();
1134
1135 } else if ( _rlen != 0 ) {
1136 rc = doTLSread();
1137
1138 } else {
1139 return;
1140 }
1141 break;
1142
1143 case TLS_write:
1144 rc = doTLSwrite();
1145 break;
1146
1147 case TLS_handshake:
1148 rc = doTLShandshake();
1149 break;
1150
1151 case TLS_close:
1152 rc = doTLSshutdown();
1153 break;
1154 }
1155
1156 if ( rc > 0 ) continue;
1157
1158 StatusIndication statusind (this);
1159
1160 switch (SSL_get_error(_ssl, rc)) {
1161 case SSL_ERROR_NONE:
1162 // No problem, carry on
1163 continue;
1164
1165 case SSL_ERROR_ZERO_RETURN:
1166 // Connection has been closed
1167 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1168 break;
1169
1170 case SSL_ERROR_WANT_READ:
1171 waitEvent (::Poll::Event_In);
1172 return;
1173
1174 case SSL_ERROR_WANT_WRITE:
1175 waitEvent (::Poll::Event_Out);
1176 return;
1177
1178 case SSL_ERROR_SYSCALL:
1179 // Check the error queue
1180 if (ERR_get_error()==0) {
1181 if (rc == 0) {
1182 // Connection has closed
1183 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1184 } else {
1185 MSG_IOevent_IOerror_SET (&statusind.msg, "SSL");
1186 }
1187 } else {
1188 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, "SSL_ERROR_SYSCALL");
1189 }
1190 break;
1191
1192 case SSL_ERROR_SSL:
1193 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, "SSL_ERROR_SSL");
1194 break;
1195
1196 case SSL_ERROR_WANT_CONNECT:
1197 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,"SSL_WANT_CONNECT");
1198 break;
1199
1200 case SSL_ERROR_WANT_ACCEPT:
1201 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror,"SSL_WANT_ACCEPT");
1202 break;
1203
1204 default:
1205 {
1206 char buf[32];
1207 snprintf (buf, sizeof buf, "err=%d", SSL_get_error(_ssl, rc));
1208 SSLTLS::SSLError (&statusind.msg, MSG_IOevent_SSLerror, buf);
1209 break;
1210 }
1211 }
1212
1213 GetUser()->Deliver (&statusind);
1214 tidy();
1215 return;
1216 }
1217}
1218
1220{
1221 // Timer has expired after EMFILE, try again
1222 waitEvent (::Poll::Event_In);
1223}
1224
1226{
1227 if ( checkUser() ) return;
1228
1229 StatusIndication statusind (this);
1230
1231 LOG_DEBUG (("SocketPoll::actualDeliver (pollmsg = %x) state=%d",
1232 msg->events, _state));
1233
1234 // Poller is no longer listening for any events
1235 _pevents = 0;
1236
1237 if ( (msg->events & ::Poll::Event_Terminate) ) {
1238 // System terminating
1239 _uevents = 0;
1240
1241 // Close first, otherwise calls back to poller
1242 closesocket (_fd);
1243 _fd = INVALID_ENDPOINT;
1244 _poller = 0;
1245
1246 // Tell User
1247 MSG_IOevent_Terminating_SET (&statusind.msg);
1248 GetUser()->Deliver (&statusind);
1249
1250 return;
1251 }
1252
1253 if ( msg->events &
1254 (::Poll::Event_Err | ::Poll::Event_Hup | ::Poll::Event_Nval) ) {
1255
1256 // Don't want any events
1257 _uevents = 0;
1258
1259 // Get error from socket
1260 int eno;
1261#ifdef GETSOCKOPT_NEEDS_INTP
1262 int olen;
1263#else
1264 socklen_t olen;
1265#endif
1266 olen = sizeof eno;
1267
1268 /* Casting to (char *) is required for Windows */
1269 int rc = getsockopt (_fd, SOL_SOCKET, SO_ERROR, (char *)&eno, &olen);
1270
1271 const char *argv[1];
1272 argv[0] = "poll";
1273
1274 MSGsetv (&statusind.msg, MSG_IOevent_IOerror, 1, argv);
1275
1276 if ( rc == 0 ) {
1277 MSGstruct sockerr;
1278 MSGsetv (&sockerr,
1279 MSGID_BUILD(MSGLEVEL_ERROR, MSGID_SYSFAC, eno),
1280 0, 0);
1281 MSGappend (&statusind.msg, &sockerr);
1282 } else {
1283 MSGappendsyserror (&statusind.msg);
1284 }
1285
1286 GetUser()->Deliver (&statusind);
1287
1288 tidy ();
1289
1290 return;
1291 }
1292
1293 // Cancel desired events
1294 _uevents &= ~msg->events;
1295
1296 if ( msg->events & ::Poll::Event_In ) {
1297
1298 switch ( _state ) {
1299 case State_tls:
1300 doTLS();
1301 break;
1302
1303 case State_connected:
1304 LOG_DEBUG (("Read stuff: _rlen = %d", (int)_rlen));
1305 if ( _rlen != 0 ) {
1306 // Stuff to read. If does not complete, then wait again
1307 if ( !doRead () )
1308 waitEvent (::Poll::Event_In);
1309 }
1310 break;
1311
1312 case State_listening:
1313 doAccept ();
1314 break;
1315
1316 default:
1317 break;
1318 }
1319 }
1320
1321 if ( msg->events & ::Poll::Event_Out ) {
1322
1323 switch ( _state ) {
1324 case State_tls:
1325 doTLS();
1326 break;
1327
1328 case State_connected:
1329 if ( _wlen != 0 ) {
1330 // Stuff to write. If does not complete, then wait again
1331 if ( !doWrite () )
1332 waitEvent (::Poll::Event_Out);
1333 }
1334 break;
1335
1336 case State_connecting:
1337 _state = State_connected;
1338 MSG_IOevent_Connected_SET (&statusind.msg);
1339 GetUser()->Deliver (&statusind);
1340 break;
1341
1342 default:
1343 break;
1344 }
1345 }
1346
1347 if ( (_uevents & ~_pevents) && _poller )
1348 _poller->Control (this);
1349}
1350
1352{
1353 if ( checkUser() ) return;
1354
1355 StatusIndication statusind (this);
1356
1357 LOG_DEBUG (("SocketPoll::actualDeliver (External)"));
1358
1359 if ( _state != State_noconnect ) {
1360 MSG_IOevent_NotConnected_SET (&statusind.msg);
1361 GetUser()->Deliver (&statusind);
1362 return;
1363 }
1364
1365 _fd = ext->fd;
1366
1367 if ( ext->listen ) {
1368 _state = State_listening;
1369
1370 waitEvent (::Poll::Event_In);
1371
1372 } else {
1373 _state = State_connected;
1374 }
1375}
1376
1378{
1379 if ( checkUser() ) return;
1380
1381 StatusIndication statusind (this);
1382
1383 LOG_DEBUG (("SocketPoll::actualDeliver (ConnectRequest)"));
1384
1385 if ( _state != State_noconnect ) {
1386 MSG_IOevent_NotConnected_SET (&statusind.msg);
1387 GetUser()->Deliver (&statusind);
1388 return;
1389 }
1390
1391 int family;
1392#if defined(AF_INET6) && defined(PF_INET6)
1393 struct sockaddr_in6 ipv6addr;
1394#endif
1395
1396 switch ( req->daddr->sa_family ) {
1397#if defined(AF_UNIX) && defined(PF_UNIX)
1398 case AF_UNIX:
1399 family = PF_UNIX;
1400 break;
1401#endif
1402
1403 case AF_INET:
1404 family = PF_INET;
1405 break;
1406
1407#if defined(AF_INET6) && defined(PF_INET6)
1408 case AF_INET6:
1409 family = PF_INET6;
1410 if ( req->dscp != 0 ) {
1411 // Set in the flowinfo in the socket address
1412 ipv6addr = * reinterpret_cast<const struct sockaddr_in6 *>
1413 (req->daddr);
1414
1415 // Note: IPv6 traffic class is offset 20 bits
1416 // and the Codepoint is the top 6 bits.
1417 ipv6addr.sin6_flowinfo = htonl (req->dscp << 22);
1418
1419 req->daddr = reinterpret_cast<struct sockaddr *>(&ipv6addr);
1420 }
1421 break;
1422#endif
1423
1424 default:
1425 MSG_IOevent_AddrType_SET (&statusind.msg, req->daddr->sa_family);
1426 GetUser()->Deliver (&statusind);
1427 return;
1428 }
1429
1430 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1431
1432 if ( fd == INVALID_ENDPOINT ) {
1433 MSG_IOevent_IOerror_SET (&statusind.msg, "socket");
1434 GetUser()->Deliver (&statusind);
1435 return;
1436 }
1437
1438#ifdef IC_WIN32
1439 // Windows sockets are inherited by default
1440 if ( SetHandleInformation ((HANDLE)fd,
1441 HANDLE_FLAG_INHERIT, // mask of bits to change
1442 0) == 0 ) {
1443 MSG_IOevent_Inherit_LOG ();
1444 }
1445#elif defined (FD_CLOEXEC)
1446 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1447#endif
1448
1449#ifdef O_NONBLOCK
1450 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1451 MSG_IOevent_IOerror_SET (&statusind.msg, "fcntl");
1452 GetUser()->Deliver (&statusind);
1453 closesocket (fd);
1454 return;
1455 }
1456#elif defined (FIONBIO)
1457 char onoff = 1;
1458 if ( ioctl (fd, FIONBIO, &onoff) != 0 ) {
1459 MSG_IOevent_IOerror_SET (&statusind.msg, "ioctl");
1460 GetUser()->Deliver (&statusind);
1461 closesocket (fd);
1462 return;
1463 }
1464#else
1465# error Cannot set socket into non-blocking more
1466#endif
1467
1468#ifdef TCP_NODELAY
1469 // Always set this on by default
1470#ifdef IC_WIN32
1471 char nodelay = 1;
1472#else
1473 int nodelay = 1;
1474#endif
1475
1476 // But ignore failure
1477 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof nodelay);
1478#endif
1479
1480 // Always set keepalives (and ignore failure)
1481#ifdef IC_WIN32
1482 char keepalive = 1;
1483#else
1484 int keepalive = 1;
1485#endif
1486 setsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,
1487 (char *)&keepalive, sizeof keepalive);
1488
1489
1490 // Set the traffic class
1491 if ( req->dscp != 0 && !setTrafficClass (fd, family, req->dscp) ) {
1492 MSG_IOevent_IOerror_SET (&statusind.msg, "traffic class");
1493 GetUser()->Deliver (&statusind);
1494 closesocket (fd);
1495 return;
1496 }
1497
1498 // Bind to the local address here, if required */
1499 if ((req->saddr) && (bind(fd, req->saddr, req->salen) == -1)) {
1500 MSG_IOevent_IOerror_SET (&statusind.msg, "bind calling address");
1501 GetUser()->Deliver (&statusind);
1502 closesocket (fd);
1503 return;
1504 }
1505
1506 if ( connect (fd, req->daddr, req->dalen) != 0 ) {
1507 isode_set_errno();
1508 if ( errno == EINPROGRESS || wouldBlock () ) {
1509 // Connect is async, need to wait
1510 _fd = fd;
1511 _state = State_connecting;
1512
1513 // Connected state indicated by socket becoming writable
1514 waitEvent (::Poll::Event_Out);
1515 } else {
1516 // Must be error in connect
1517 MSG_IOevent_IOerror_SET (&statusind.msg, "connect");
1518 GetUser()->Deliver (&statusind);
1519 closesocket (fd);
1520 }
1521
1522 } else {
1523 // Immediate connection
1524
1525 _fd = fd;
1526 _state = State_connected;
1527
1528 MSG_IOevent_Connected_SET (&statusind.msg);
1529 GetUser()->Deliver (&statusind);
1530 }
1531}
1532
1533bool Stream::SocketPoll::setTrafficClass (
1534 endpoint_t fd,
1535 int family,
1536 unsigned traffic_class)
1537{
1538 if ( family == PF_INET ) {
1539 // IPv4
1540 // traffic class is in TOS byte, low 2 bits are not used
1541 int tosbyte = traffic_class << 2;
1542#ifdef IP_TOS
1543# ifdef SOL_IP
1544# define TOSLEVEL SOL_IP
1545# else
1546# define TOSLEVEL IPPROTO_IP
1547# endif
1548 return setsockopt (fd, TOSLEVEL, IP_TOS,
1549 (char *)&tosbyte, sizeof tosbyte) == 0;
1550#else
1551 return false;
1552#endif
1553 }
1554
1555 // If IPv6 then already actioned, otherwise ignore
1556 return true;
1557}
1558
1560{
1561 if ( checkUser() ) return;
1562
1563 StatusIndication statusind (this);
1564
1565 LOG_DEBUG (("SocketPoll::actualDeliver (ListenRequest)"));
1566
1567 if ( _state != State_noconnect ) {
1568 MSG_IOevent_NotConnected_SET (&statusind.msg);
1569
1570 GetUser()->Deliver (&statusind);
1571
1572 return;
1573 }
1574
1575 int family;
1576
1577 switch ( req->laddr->sa_family ) {
1578#ifdef AF_UNIX
1579 case AF_UNIX:
1580 family = PF_UNIX;
1581 break;
1582#endif
1583
1584 case AF_INET:
1585 family = PF_INET;
1586 break;
1587
1588#if defined(AF_INET6) && defined(PF_INET6)
1589 case AF_INET6:
1590 family = PF_INET6;
1591 break;
1592#endif
1593
1594 default:
1595 MSG_IOevent_AddrType_SET (&statusind.msg, req->laddr->sa_family);
1596 GetUser()->Deliver (&statusind);
1597 return;
1598 }
1599
1600 endpoint_t fd = socket (family, SOCK_STREAM, 0);
1601
1602 if ( fd == INVALID_ENDPOINT ) {
1603 MSG_IOevent_IOerror_SET (&statusind.msg, "socket");
1604 GetUser()->Deliver (&statusind);
1605 return;
1606 }
1607
1608#if defined(PF_INET6) && defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
1609 if ( family == PF_INET6 ) {
1610 int v6only = 1;
1611
1612 if ( setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY,
1613 (char *)&v6only, sizeof v6only) != 0 ) {
1614 MSG_IOevent_IOerror_SET (&statusind.msg, "setsockopt");
1615 GetUser()->Deliver (&statusind);
1616 closesocket (fd);
1617 return;
1618 }
1619 }
1620#endif
1621
1622#if !defined(IC_WIN32) && defined(SO_REUSEADDR)
1623 int onoff = 1;
1624
1625 if ( setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
1626 (char *)&onoff, sizeof onoff) != 0 ) {
1627 MSG_IOevent_IOerror_SET (&statusind.msg, "setsockopt");
1628 GetUser()->Deliver (&statusind);
1629 closesocket (fd);
1630 return;
1631 }
1632#endif
1633
1634 if ( bind (fd, req->laddr, req->lalen ) != 0 ) {
1635 MSG_IOevent_IOerror_SET (&statusind.msg, "bind");
1636 GetUser()->Deliver (&statusind);
1637 closesocket (fd);
1638 return;
1639 }
1640
1641#ifdef IC_WIN32
1642 // Windows sockets are inherited by default
1643 if ( SetHandleInformation ((HANDLE)fd,
1644 HANDLE_FLAG_INHERIT, // mask of bits to change
1645 0) == 0 ) {
1646 MSG_IOevent_Inherit_LOG ();
1647 }
1648#elif defined (FD_CLOEXEC)
1649 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
1650#endif
1651
1652#ifdef O_NONBLOCK
1653 if ( fcntl (fd, F_SETFL, O_NONBLOCK) != 0 ) {
1654 MSG_IOevent_IOerror_SET (&statusind.msg, "fcntl");
1655 GetUser()->Deliver (&statusind);
1656 closesocket (fd);
1657 return;
1658 }
1659#elif defined (FIONBIO)
1660 char con = 1;
1661 if ( ioctl (fd, FIONBIO, &con) != 0 ) {
1662 MSG_IOevent_IOerror_SET (&statusind.msg, "ioctl");
1663 GetUser()->Deliver (&statusind);
1664 closesocket (fd);
1665 return;
1666 }
1667#else
1668# error Cannot set socket into non-blocking more
1669#endif
1670
1671 if ( listen (fd, req->backlog ? req->backlog : SOMAXCONN) != 0 ) {
1672 MSG_IOevent_IOerror_SET(&statusind.msg, "listen");
1673 GetUser()->Deliver (&statusind);
1674 closesocket (fd);
1675 return;
1676 }
1677
1678 // Listening
1679 _fd = fd;
1680 _state = State_listening;
1681
1682 // Listen events are 'In' events
1683 waitEvent (::Poll::Event_In);
1684}
1685
1687{
1688 if ( checkUser() ) return;
1689
1690 StatusIndication statusind (this);
1691
1692 LOG_DEBUG (("SocketPoll::actualDeliver (ConnectAccept)"));
1693
1694 if ( _fd == INVALID_ENDPOINT || _state != State_accepting ) {
1695 MSG_IOevent_NotConnected_SET (&statusind.msg);
1696
1697 GetUser()->Deliver (&statusind);
1698
1699 return;
1700 }
1701
1702 // For a socket interface there is nothing to do to accept the connection
1703 _state = State_connected;
1704}
1705
1707{
1708 if ( checkUser() ) return;
1709
1710 StatusIndication statusind (this);
1711
1712 LOG_DEBUG (("SocketPoll::actualDeliver (DisconnectRequest)"));
1713
1714 switch ( _state ) {
1715 case State_connected:
1716 case State_accepting:
1717 case State_tls:
1718 if ( _fd != INVALID_ENDPOINT )
1719 break;
1720 BOOST_FALLTHROUGH;
1721
1722 default:
1723 MSG_IOevent_NotConnected_SET (&statusind.msg);
1724 GetUser()->Deliver (&statusind);
1725 return;
1726 }
1727
1728 if ( _state == State_tls ) {
1729 _tlsstate = TLS_close;
1730
1731 doTLS();
1732
1733 } else {
1734 // Close up connection, etc.
1735
1736 MSG_IOevent_ConnectionClosed_SET (&statusind.msg);
1737 GetUser()->Deliver (&statusind);
1738
1739 tidy ();
1740 }
1741}
1742
1744{
1745 if ( checkUser() ) return;
1746
1747 StatusIndication statusind (this);
1748
1749 LOG_DEBUG (("SocketPoll::actualDeliver (DataRequest) state=%d _wlen=%ld",
1750 _state, (long)_wlen));
1751
1752 switch ( _state ) {
1753 case State_connected:
1754 case State_tls:
1755 if ( _fd != INVALID_ENDPOINT )
1756 break;
1757 BOOST_FALLTHROUGH;
1758
1759 default:
1760 MSG_IOevent_NotConnected_SET (&statusind.msg);
1761 GetUser()->Deliver (&statusind);
1762 return;
1763 }
1764
1765 // Note: should not attempt to write zero bytes
1766 if ( req->buf == 0 || req->len == 0 ) {
1767 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
1768 req->buf == NULL ?
1769 "buffer pointer" :
1770 "zero length");
1771
1772 GetUser()->Deliver (&statusind);
1773
1774 return;
1775 }
1776
1777 if ( _wlen != 0 ) {
1778 ReleaseBuf release;
1779
1780 release.buf = req->buf;
1781 release.len = -1;
1782
1783 GetUser()->Deliver (&release);
1784
1785 MSG_IOevent_DupWrite_SET (&statusind.msg);
1786
1787 GetUser()->Deliver (&statusind);
1788
1789 return;
1790 }
1791
1792 _wbuf = _wptr = req->buf;
1793 _wlen = req->len;
1794
1795 if ( _state == State_connected ) {
1796 if ( !doWrite () ) {
1797 // Write blocked, tell poller we want to know when can write
1798 waitEvent (::Poll::Event_Out);
1799 }
1800
1801 } else {
1802 doTLS();
1803 }
1804}
1805
1807{
1808 if ( checkUser() ) return;
1809
1810 DataIndication dataind;
1811 StatusIndication statusind (this);
1812
1813 LOG_DEBUG (("SocketPoll::actualDeliver (ReadRequest)"));
1814
1815 switch ( _state ) {
1816 case State_connected:
1817 case State_tls:
1818 if ( _fd != INVALID_ENDPOINT )
1819 break;
1820 BOOST_FALLTHROUGH;
1821
1822 default:
1823 MSG_IOevent_NotConnected_SET (&statusind.msg);
1824 GetUser()->Deliver (&statusind);
1825 return;
1826 }
1827
1828 if ( req->buf == 0 || req->len == 0 ) {
1829 MSG_IOevent_InvalidParameter_SET (&statusind.msg,
1830 req->buf == NULL ?
1831 "buffer pointer" :
1832 "zero length");
1833
1834 GetUser()->Deliver (&statusind);
1835
1836 return;
1837 }
1838
1839 if ( _rlen != 0 ) {
1840 dataind.buf = req->buf;
1841 dataind.len = -1;
1842
1843 GetUser()->Deliver (&dataind);
1844
1845 MSG_IOevent_DupRead_SET (&statusind.msg);
1846
1847 GetUser()->Deliver (&statusind);
1848
1849 return;
1850 }
1851
1852 _rbuf = _rptr = req->buf;
1853 _rlen = req->len;
1854 _rfill = req->fill;
1855
1856 LOG_DEBUG (("ReadRequest: _rbuf=%p _rlen=%d _rfill=%d",
1857 _rbuf, (int)_rlen, _rfill));
1858
1859 if ( _state == State_connected ) {
1860 // If the previous read filled the provided buffer, then
1861 // we attempt a read at this point. There may be more data
1862 // already buffered in the OS
1863
1864 if ( _rfull && doRead () )
1865 return;
1866
1867 // tell poller we are interested in read events
1868 waitEvent (::Poll::Event_In);
1869
1870 } else {
1871 doTLS();
1872 }
1873}
1874
1876{
1877 if ( checkUser() ) return;
1878
1879 LOG_DEBUG (("SocketPoll::actualDeliver (StartTLS)"));
1880
1881 StatusIndication statusind (this);
1882
1883 switch ( _state ) {
1884 case State_tls:
1885 MSG_IOevent_SSLalready_SET (&statusind.msg);
1886 GetUser()->Deliver (&statusind);
1887 return;
1888
1889 case State_connected:
1890 if ( _fd != INVALID_ENDPOINT )
1891 break;
1892 BOOST_FALLTHROUGH;
1893
1894 default:
1895 MSG_IOevent_NotConnected_SET (&statusind.msg);
1896 GetUser()->Deliver (&statusind);
1897 return;
1898 }
1899
1900 // Only check hostname of server
1901 _hostname = req->client ? req->hostname : 0;
1902
1903 SSLTLS::OpenSSLContext *sslctx =
1904 dynamic_cast<SSLTLS::OpenSSLContext *>(req->context);
1905
1906 _ssl = sslctx ? sslctx->GetSSL(_choice) : NULL;
1907 if (!_ssl) {
1908 MSG_IOevent_SSLerror_SET (&statusind.msg, "SSL_new", "this returned NULL. No ID configured?");
1909 GetUser()->Deliver (&statusind);
1910 return;
1911 }
1912
1913 // Check for any OpenSSL error set during previous use of this thread
1914 int err = SSL_get_error(_ssl, 0);
1915 if (err != SSL_ERROR_NONE) {
1916 // Report but clear and continue
1917 LOG_DEBUG (("SocketPoll::actualDeliver(StartTLS) - SSL error code %d", err));
1918 ERR_clear_error();
1919 }
1920
1921 BIO *bio = BIO_new_socket (_fd, TRUE);
1922
1923 SSL_set_bio(_ssl, bio, bio);
1924
1925 if ( req->client )
1926 SSL_set_connect_state (_ssl);
1927 else
1928 SSL_set_accept_state (_ssl);
1929
1930 _state = State_tls;
1931 _tlsstate = TLS_handshake;
1932
1933 doTLS();
1934}
1935
1937{
1938 if ( checkUser() ) return;
1939
1940 LOG_DEBUG (("SocketPoll::actualDeliver (StreamControl)"));
1941
1942 StatusIndication statusind (this);
1943
1944 if ( _fd == INVALID_ENDPOINT ) {
1945 MSG_IOevent_NotConnected_SET (&statusind.msg);
1946 GetUser()->Deliver (&statusind);
1947 return;
1948 }
1949
1950 int level;
1951 int name;
1952
1953 switch ( option->option ) {
1954#if defined(TCP_NODELAY)
1955 case StreamControlNoDelay:
1956 level = IPPROTO_TCP;
1957 name = TCP_NODELAY;
1958 break;
1959#endif
1960
1962 level = SOL_SOCKET;
1963 name = SO_KEEPALIVE;
1964 break;
1965
1966#if defined(IP_TOS)
1967 case StreamControlTOS:
1968#ifdef SOL_IP
1969 level = SOL_IP;
1970#else
1971 level = IPPROTO_IP;
1972#endif
1973 name = IP_TOS;
1974 break;
1975#endif
1976
1977 default:
1978 MSG_IOevent_UnknownStreamOpt_SET (&statusind.msg, option->option);
1979 GetUser()->Deliver (&statusind);
1980 return;
1981 }
1982
1983 int rc = setsockopt (_fd, level, name, (char *)&option->value, sizeof option->value);
1984 if ( rc != 0 ) {
1985 MSG_IOevent_IOerror_SET (&statusind.msg, "setsockopt");
1986 GetUser()->Deliver (&statusind);
1987 tidy ();
1988 }
1989}
1990
1991
1992Stream::Provider *Stream::CreateSocketPollProvider ()
1993{
1994 // In a single-threaded environment COULD create a SocketPoll
1995 return new Stream::SyncSocketPoll;
1996}
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.
virtual int GetPeerAddress(struct sockaddr *laddr, socklen_t *lalenp, MSGstruct *msp)
Get the peer address.
virtual void Deliver(ConnectRequest *req)
connect
virtual void Deliver(::Poll::pollmsg *msg)
Deliver events to Poll provider.
virtual void Deliver(time_t *msg)
Handle timer event.
virtual SocketPoll * Clone()=0
Make another provider like this one.
void tidy()
Tidy up - close connections etc.
virtual int GetLocalAddress(struct sockaddr *laddr, socklen_t *lalenp, MSGstruct *msp)
Get the local address.
void actualDeliver(time_t *msg)
Handle timer event.
virtual void Deliver(ListenRequest *req)
listen
virtual unsigned Events()
Get the events.
void actualDeliver(DisconnectRequest *req)
disconnect
virtual X509 * GetPeerCertificate()
Get the peer certificate.
virtual void Deliver(ConnectAccept *req)
accept
virtual TLS_CipherSuite GetCipherSuite()
Get the cipher suite.
virtual void Deliver(StreamControl *option)
Control stream.
virtual void Deliver(StartTLS *req)
Start SSL/TLS on stream.
void actualDeliver(ConnectAccept *req)
accept
virtual endpoint_t GetEndpoint(bool inheriting)
Get the endpoint ID.
virtual void Deliver(External *ext)
Set external.
virtual void Deliver(LengthFnxRequest *)
Set length function.
virtual void Deliver(ReadRequest *req)
Read request.
virtual void Die()
Make this provider go away.
virtual void Deliver(DisconnectRequest *req)
disconnect
virtual void Deliver(DataRequest *req)
send data
virtual void Deliver(ListenRequest *req)
listen
virtual void Die()
Make this go away.
virtual void Deliver(::Poll::pollmsg *msg)
Deliver events from Poll provider.
virtual SocketPoll * Clone()
Make one like this.
virtual void Deliver(External *ext)
Set external.
virtual void Deliver(ReadRequest *req)
Read request.
virtual void Deliver(ConnectRequest *req)
connect
virtual void Deliver(StreamControl *option)
Control stream.
virtual void Deliver(time_t *msg)
Handle timer event.
virtual void Deliver(ConnectAccept *req)
accept
virtual void Deliver(DataRequest *req)
send data
virtual void Deliver(StartTLS *req)
Start SSL/TLS on stream.
virtual void Deliver(DisconnectRequest *req)
disconnect
virtual void Deliver(ConnectIndication *data)=0
Connection indication.
Class used to wrap each event object type for a given receiver.
Definition Syncmsg.h:30
void Init(C *rcvr)
Set the target.
Definition Syncmsg.h:48
Template class for protecting an object.
Definition Syncmsg.h:166
void msgDeliver(M *msg)
template function for delivering message of given type to receiver
Definition Syncmsg.h:288
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.