@@ -93,11 +93,18 @@ DEF_TRANSITION_GRAPH
93
93
ON (FINISH) SET_STATE_TO(CLOSING) AND_INVOKE(CloseSocket)
94
94
END_DEF
95
95
96
+ DEFINE_STATE (SSL_HANDSHAKE)
97
+ ON (WAKEUP) SET_STATE_TO(SSL_HANDSHAKE) AND_WAIT
98
+ ON (NEED_DATA) SET_STATE_TO(SSL_HANDSHAKE) AND_WAIT
99
+ ON (PROCEED) SET_STATE_TO(PROCESS) AND_INVOKE(Process)
100
+ END_DEF
101
+
96
102
DEFINE_STATE (PROCESS)
97
103
ON (PROCEED) SET_STATE_TO(WRITE) AND_INVOKE(ProcessWrite)
98
104
ON (NEED_DATA) SET_STATE_TO(READ) AND_INVOKE(FillReadBuffer)
99
105
ON (GET_RESULT) SET_STATE_TO(GET_RESULT) AND_WAIT
100
106
ON (FINISH) SET_STATE_TO(CLOSING) AND_INVOKE(CloseSocket)
107
+ ON (SSL_HANDSHAKE) SET_STATE_TO(SSL_HANDSHKE) AND_INVOKE(SSL_handshake)
101
108
END_DEF
102
109
103
110
DEFINE_STATE (WRITE)
@@ -641,6 +648,93 @@ Transition ConnectionHandle::Wait() {
641
648
return Transition::PROCEED;
642
649
}
643
650
651
+ Transition ConnectionHandle::SSL_handshake () {
652
+
653
+ if (conn_SSL_context == nullptr ) {
654
+ // TODO(Tianyi) encapsulate this
655
+ conn_SSL_context = SSL_new (PelotonServer::ssl_context);
656
+ if (conn_SSL_context == nullptr ) {
657
+ throw NetworkProcessException (" ssl context for conn failed" );
658
+ }
659
+ SSL_set_session_id_context (conn_SSL_context, nullptr , 0 );
660
+ if (SSL_set_fd (conn_SSL_context, sock_fd_) == 0 ) {
661
+ LOG_ERROR (" Failed to set SSL fd" );
662
+ PL_ASSERT (false );
663
+ }
664
+ }
665
+
666
+ bool handshake_fail = false ;
667
+ // TODO(Yuchen): post-connection verification?
668
+ while (!handshake_fail) {
669
+ // clear current thread's error queue before any OpenSSL call
670
+ ERR_clear_error ();
671
+ int ssl_accept_ret = SSL_accept (conn_SSL_context);
672
+ if (ssl_accept_ret > 0 ) {
673
+ break ;
674
+ }
675
+ int err = SSL_get_error (conn_SSL_context, ssl_accept_ret);
676
+ int ecode = ERR_get_error ();
677
+ char error_string[120 ];
678
+ ERR_error_string (ecode, error_string);
679
+ switch (err) {
680
+ case SSL_ERROR_SSL: {
681
+ if (ecode < 0 ) {
682
+ LOG_ERROR (" Could not accept SSL connection" );
683
+ } else {
684
+ LOG_ERROR (
685
+ " Could not accept SSL connection: EOF detected, "
686
+ " ssl_error_ssl, %s" ,
687
+ error_string);
688
+ }
689
+ handshake_fail = true ;
690
+ break ;
691
+ }
692
+ case SSL_ERROR_ZERO_RETURN: {
693
+ LOG_ERROR (
694
+ " Could not accept SSL connection: EOF detected, "
695
+ " ssl_error_zero_return, %s" ,
696
+ error_string);
697
+ handshake_fail = true ;
698
+ break ;
699
+ }
700
+ case SSL_ERROR_SYSCALL: {
701
+ if (ecode < 0 ) {
702
+ LOG_ERROR (" Could not accept SSL connection, %s" , error_string);
703
+ } else {
704
+ LOG_ERROR (
705
+ " Could not accept SSL connection: EOF detected, "
706
+ " ssl_sys_call, %s" ,
707
+ error_string);
708
+ }
709
+ handshake_fail = true ;
710
+ break ;
711
+ }
712
+ case SSL_ERROR_WANT_READ: {
713
+ UpdateEventFlags (EV_READ | EV_PERSIST);
714
+ break ;
715
+ }
716
+ case SSL_ERROR_WANT_WRITE: {
717
+ UpdateEventFlags (EV_WRITE | EV_PERSIST);
718
+ break ;
719
+ }
720
+ default : {
721
+ LOG_ERROR (" Unrecognized SSL error code: %d" , err);
722
+ handshake_fail = true ;
723
+ }
724
+ }
725
+ }
726
+ if (!handshake_fail) {
727
+ // handshake succeeds, reset ssl_sent_
728
+ ssl_handshake_ = false ;
729
+ finish_startup_packet_ = false ;
730
+ return Transition::NEED_DATA;
731
+ } else {
732
+ throw NetworkProcessException (" SSL handshake failure" );
733
+ }
734
+
735
+
736
+ }
737
+
644
738
Transition ConnectionHandle::Process () {
645
739
// TODO(tianyu): further simplify this logic
646
740
if (!finish_startup_packet_) {
0 commit comments