[ 
https://issues.apache.org/jira/browse/TS-4322?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15514384#comment-15514384
 ] 

James Peach commented on TS-4322:
---------------------------------

[~oknet] while people are reviewing this code, could you work with [~zwoop] to 
run the patch on docs.trafficserver.apache.org to get some real-world usage?

> ProfileSM Proposal
> ------------------
>
>                 Key: TS-4322
>                 URL: https://issues.apache.org/jira/browse/TS-4322
>             Project: Traffic Server
>          Issue Type: Improvement
>          Components: Core, Network
>            Reporter: Oknet Xu
>             Fix For: sometime
>
>         Attachments: ATS SslProfileSMv1.png, ATS TcpProfileSM.png
>
>
> Preface
> =======
> NetVConnection is a base class for all NetIO derived classes:
>   - NetVConnection
>     - UnixNetVConnection for TCP NetIO
>       - SSLNetVConnection for SSL NetIO
> with the below codes to test a NetVC whether is a SSLNetVC :
> {code}
>   sslvc = dynamic_cast<SSLNetVConnection *>netvc;
>   if (sslvc != NULL)
>   {
>      // netvc is a SSLNetVConnection
>   } else {
>      // netvc is a UnixNetVConnection
>   }
> {code}
> ATS support HTTP, SPDY and H2 protocol, and also support them with SSL/TLS.
> Sometimes we want to talk in HTTP/TCP first, and then talk in HTTP/SSL,
> Example : HTTPS over HTTP CONNECT method
> {code}
> Client send a CONNECT method request
>     C->P: CONNECT www.example.com:443 HTTP/1.1
>     C->P: Host: www.example.com:443
>     C->P:
> ATS reply a HTTP 200/OK, then build a TCP tunnel to www.example.com:443
>     P->C: 200 OK
>     P->C: 
> Client send a SSL Handshake Client Hello message
>     C->P: <Client Hello>
> ATS tunnel the message
>     P->S: <Client Hello>
> Server response a SSL Handshake Server Hello message
>     P<-S: <Server Hello>
> ATS tunnel the message
>     C<-P: <Server Hello>
> Server send a Certificate to ATS
>     P<-S: <Certificate>
> ATS tunnel the message
>     C<-P: <Certificate>
> etc . . .
> {code}
> currently, It isn't a easy way upgrading to SSLNetVConnection from 
> UnixNetVConnection.
> the ProfileSM is designed to setup a plugable mechanism for 
> UnixNetVConnection to handle(abstract) different type of I/O operation.
> so we will have TcpProfileSM and UdpProfileSM as low level ProfileSM and 
> SslProfileSM as high level ProfileSM.
> How to implement
> ================
> Introduce a new class ProfileSM & TcpProfileSM & SslProfileSM :
> It is a derived class from Continuation
> - Has handleEvent() function
> - Has mutex member
> TcpProfileSM is a derived class from ProfileSM
> SslProfileSM is a derived class from ProfileSM
> handshakeEvent(int event, void *data) function
> - only defined in SslProfileSM
> - the SSL handshake handle function
> - `event' can be IOCORE_EVENTS_READ or IOCORE_EVENTS_WRITE
> - it is callback from NetHandler::mainNetEvent()
> - `data' is a pointer to Nethandler type
> - it is implement NPN/ALPN support and replace SSLNextProtocolAccept & 
> SSLNextProtocolTrampoline, pick some codes from sslvc->net_read_io(), 
> write_to_net_io()
> - set Continuation->handler to mainEvent() when HandShake done.
> mainEvent(int event, void *data) function
> - the first entrance
> - `event' can be IOCORE_EVENTS_READ or IOCORE_EVENTS_WRITE
> - it is callback from NetHandler::mainNetEvent()
> - `data' is a pointer to Nethandler type
> handle_read(NetHandler *nh, EThread *lthread)
> - it is called by mainEvent() if event is IOCORE_EVENTS_READ
> - for TcpProfileSM, it call vc->net_read_io(nh, lthread)
> - for SslProfileSM, it call sslvc->net_read_io(nh, lthread)
> handle_write(NetHandler *nh, EThread *lthread)
> - it is called by mainEvent() if event is IOCORE_EVENTS_WRITE
> - for TcpProfileSM, it call write_to_net(nh, lthread)
> - for SslProfileSM, it call write_to_net(nh, lthread)
> raw_read() and raw_readv()
> - for TcpProfileSM, it is wrap for syscall read() & readv()
> - for SslProfileSM, it is wrap for SSL_read()
> raw_write() and raw_writev()
> - for TcpProfileSM, it is wrap for syscall write() & writev()
> - for SslProfileSM, it is wrap for SSL_write()
> ProfileSM *low_profilesm;
> - for TcpProfileSM, it set to NULL
> - for SslProfileSM, it set to TcpProfileSM
> minor change in functions
> - vc->net_read_io()
> - sslvc->net_read_io()
> - read_from_net()
> - ssl_read_from_net()
> - write_to_net(), write_to_net_io()
> - vc->load_buffer_and_write()
> - sslvc->load_buffer_and_write()
> add misc for SslProfileSM (reference SSLUnixNetVConnection)
> - SSL *ssl;
> - MIOBuffer *handshakebuffer
> At last,
> add ProfileSM *profile_sm to UnixNetVConnection as a member
> modify NetHandler::mainNetEvent()
> - vc->net_read_io(this, trigger_event->ethread);
> - change to
> - vc->profile_sm->handleEvent(IOCORE_EVENTS_READ, this);
> - write_to_net(this, vc, trigger_event->ethread);
> - change to
> - vc->profile_sm->handleEvent(IOCORE_EVENTS_WRITE, this);
> New World
> =========
> the UnixNetVConnection with new TcpProfileSM and HttpSM process:
> NetAccept 
> - new UnixNetVC 
> - new TcpProfileSM
> - attach TcpProfileSM to UnixNetVC
> - callback NET_EVENT_ACCEPT to ProtocolProbeAccept::mainEvent()
> ProtocolProbeAccept::mainEvent()
> - probe = new ProtocolProbeTrampoline(this, netvc->mutex, buf, reader);
> - vio = netvc->do_io_read(probe, buffer_size, probe->iobuf);
> - vio->reenable();
> NetHandler::mainNetEvent()
> - callback IOCORE_EVENTS_READ to TcpProfileSM
> TcpProfileSM::mainEvent()
> - call handle_read()
> - raw_read()
> - callback ProtocolProbeTrampoline::ioCompletionEvent(VC_EVENT_READ_COMPLETE, 
> vio)
> - ProtocolProbe and create HttpSessionAccept()
> the UnixNetVConnection with new TcpProfileSM, SslProfileSM and HttpSM process:
> NetAccept 
> - new UnixNetVC 
> - new TcpProfileSM
> - attach TcpProfileSM to UnixNetVC
> - new SslProfileSM
> - attach TcpProfileSM to UnixNetVC
> - callback NET_EVENT_ACCEPT to ProtocolProbeAccept::mainEvent()
> ProtocolProbeAccept::mainEvent()
> - probe = new ProtocolProbeTrampoline(this, netvc->mutex, buf, reader);
> - vio = netvc->do_io_read(probe, buffer_size, probe->iobuf);
> - vio->reenable();
> NetHandler::mainNetEvent()
> - callback IOCORE_EVENTS_READ to SslProfileSM
> SslProfileSM::handshakeEvent()
> - call make_ssl_connection() to initlization SSL/CTX
> - raw_read() and create rBIO with handshake buffer
> - call SSL_accept()
> - if handshake done, free handshake buffer then set handler to mainEvent
> - if handshake error, copy handshake buffer into low_profilesm, deattach 
> SslProfileSM and set vc->profile_sm = low_profilesm
> - read_reschedule(vc) if ssl_want_read or vc->read.vio was set
> - write_reschedule(vc) if ssl_want_write or vc->write.vio was set
> SslProfileSM::mainEvent()
> - call handle_read()
> - raw_read()
> - callback ProtocolProbeTrampoline::ioCompletionEvent(VC_EVENT_READ_COMPLETE, 
> vio)
> - ProtocolProbe and create HttpSessionAccept()
> TcpProfileSM::mainEvent()
> - call handle_read()
> - move handshake buffer to vio buffer if handshake buffer existed
> - raw_read()
> - callback ProtocolProbeTrampoline::ioCompletionEvent(VC_EVENT_READ_COMPLETE, 
> vio)
> - ProtocolProbe and create HttpSessionAccept()
> the SSLNetVConnection could be replaced by the above process.
> the UnixNetVConnection only as a resource container, saved
>   - socket fd
>   - read vio
>   - writw vio
> and has a timeout control mechanism with InactivityCop.
> with SslProfileSM, ATS doesn't care if a NetVC is a SSLNetVC. which means ATS 
> can handle TCP & SSL connection in the same way by UnixNetVConnection.
> so we can delete these lines from ATS:
> {code}
> proxy/http/HttpClientSession.cc
>   if (!iobuf) {
>     SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(new_vc);
>     if (ssl_vc) {
>       iobuf = ssl_vc->get_ssl_iobuf();
>       sm_reader = ssl_vc->get_ssl_reader();
>     }   
>   }
> proxy/http2/Http2SessionAccept.cc
>     if (ssl_vc) {
>       iobuf = ssl_vc->get_ssl_iobuf();
>       reader = ssl_vc->get_ssl_reader();
>     }   
> proxy/spdy/SpdySessionAccept.cc
>     if (ssl_vc) {
>       iobuf = ssl_vc->get_ssl_iobuf();
>       reader = ssl_vc->get_ssl_reader();
>     }   
> {code}
> SSLNextProtocolTrampoline has a member `iobuf', it is used to save first 
> content and transfer into ProtocolProbeAccept as a protocol probe buffer.
> thus, HttpSM/SpdySM/H2SM should check the type of vc and get the right probe 
> buffer,  `sslvc->iobuf' or `this->iobuf'.
> Merge SSLNextProtocolAccept and SSLNextProtocolTrampoline into SslProfileSM 
> and modify ProtocolProbeTrampoline to accept `Protocol Type' from 
> SslProfileSM by NPN/ALPN.
> After the code merged, only one protocol probe buffer in 
> ProtocolProbeTrampoline, and doesn't need check the type of vc.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to