Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "P_SSLNextProtocolAccept.h"
00025 
00026 static void
00027 send_plugin_event(Continuation * plugin, int event, void * edata)
00028 {
00029   if (plugin->mutex) {
00030     EThread * thread(this_ethread());
00031     MUTEX_TAKE_LOCK(plugin->mutex, thread);
00032     plugin->handleEvent(event, edata);
00033     MUTEX_UNTAKE_LOCK(plugin->mutex, thread);
00034   } else {
00035     plugin->handleEvent(event, edata);
00036   }
00037 }
00038 
00039 static SSLNetVConnection *
00040 ssl_netvc_cast(int event, void * edata)
00041 {
00042   union {
00043     VIO * vio;
00044     NetVConnection * vc;
00045   } ptr;
00046 
00047   switch (event) {
00048   case NET_EVENT_ACCEPT:
00049     ptr.vc = static_cast<NetVConnection *>(edata);
00050     return dynamic_cast<SSLNetVConnection *>(ptr.vc);
00051   case VC_EVENT_INACTIVITY_TIMEOUT:
00052   case VC_EVENT_READ_COMPLETE:
00053   case VC_EVENT_ERROR:
00054     ptr.vio = static_cast<VIO *>(edata);
00055     return dynamic_cast<SSLNetVConnection *>(ptr.vio->vc_server);
00056   default:
00057     return NULL;
00058   }
00059 }
00060 
00061 
00062 
00063 
00064 
00065 
00066 struct SSLNextProtocolTrampoline : public Continuation
00067 {
00068   explicit
00069   SSLNextProtocolTrampoline(const SSLNextProtocolAccept * npn, ProxyMutex* mutex)
00070     : Continuation(mutex), npnParent(npn)
00071   {
00072     SET_HANDLER(&SSLNextProtocolTrampoline::ioCompletionEvent);
00073   }
00074 
00075   int ioCompletionEvent(int event, void * edata)
00076   {
00077     VIO * vio;
00078     Continuation * plugin;
00079     SSLNetVConnection * netvc;
00080 
00081     vio = static_cast<VIO *>(edata);
00082     netvc = dynamic_cast<SSLNetVConnection *>(vio->vc_server);
00083     ink_assert(netvc != NULL);
00084 
00085     switch (event) {
00086     case VC_EVENT_EOS:
00087     case VC_EVENT_ERROR:
00088     case VC_EVENT_ACTIVE_TIMEOUT:
00089     case VC_EVENT_INACTIVITY_TIMEOUT:
00090       netvc->do_io(VIO::CLOSE);
00091       delete this;
00092       return EVENT_CONT;
00093     case VC_EVENT_READ_COMPLETE:
00094       break;
00095     default:
00096       return EVENT_ERROR;
00097     }
00098 
00099     plugin = netvc->endpoint();
00100     if (plugin) {
00101       send_plugin_event(plugin, NET_EVENT_ACCEPT, netvc);
00102     } else if (npnParent->endpoint) {
00103       
00104       send_plugin_event(npnParent->endpoint, NET_EVENT_ACCEPT, netvc);
00105     } else {
00106       
00107       netvc->do_io(VIO::CLOSE);
00108     }
00109 
00110     delete this;
00111     return EVENT_CONT;
00112   }
00113 
00114   const SSLNextProtocolAccept * npnParent;
00115 };
00116 
00117 int
00118 SSLNextProtocolAccept::mainEvent(int event, void * edata)
00119 {
00120   SSLNetVConnection * netvc = ssl_netvc_cast(event, edata);
00121 
00122   netvc->sslHandshakeBeginTime = ink_get_hrtime();
00123   Debug("ssl", "[SSLNextProtocolAccept:mainEvent] event %d netvc %p", event, netvc);
00124 
00125   switch (event) {
00126   case NET_EVENT_ACCEPT:
00127     ink_release_assert(netvc != NULL);
00128     
00129     
00130     
00131     
00132     netvc->registerNextProtocolSet(&this->protoset);
00133     netvc->do_io(VIO::READ, new SSLNextProtocolTrampoline(this, netvc->mutex), 0, this->buffer, 0);
00134     return EVENT_CONT;
00135   default:
00136     netvc->do_io(VIO::CLOSE);
00137     return EVENT_DONE;
00138   }
00139 }
00140 
00141 void
00142 SSLNextProtocolAccept::accept(NetVConnection *, MIOBuffer *, IOBufferReader *)
00143 {
00144   ink_release_assert(0);
00145 }
00146 
00147 bool
00148 SSLNextProtocolAccept::registerEndpoint(
00149     const char * protocol, Continuation * handler)
00150 {
00151   return this->protoset.registerEndpoint(protocol, handler);
00152 }
00153 
00154 bool
00155 SSLNextProtocolAccept::unregisterEndpoint(
00156     const char * protocol, Continuation * handler)
00157 {
00158   return this->protoset.unregisterEndpoint(protocol, handler);
00159 }
00160 
00161 SSLNextProtocolAccept::SSLNextProtocolAccept(Continuation * ep)
00162     : SessionAccept(NULL), buffer(new_empty_MIOBuffer()), endpoint(ep)
00163 {
00164   SET_HANDLER(&SSLNextProtocolAccept::mainEvent);
00165 }
00166 
00167 SSLNextProtocolAccept::~SSLNextProtocolAccept()
00168 {
00169   free_MIOBuffer(this->buffer);
00170 }