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 "ink_config.h"
00025 #include "apidefs.h"
00026 #include "libts.h"
00027 #include "P_SSLNextProtocolSet.h"
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 unsigned char *
00037 append_protocol(const char * proto, unsigned char * buf)
00038 {
00039   size_t sz = strlen(proto);
00040   *buf++ = (unsigned char)sz;
00041   memcpy(buf, proto, sz);
00042   return buf + sz;
00043 }
00044 
00045 static bool
00046 create_npn_advertisement(
00047   const SSLNextProtocolSet::NextProtocolEndpoint::list_type& endpoints,
00048   unsigned char ** npn, size_t * len)
00049 {
00050   const SSLNextProtocolSet::NextProtocolEndpoint * ep;
00051   unsigned char * advertised;
00052 
00053   *npn = NULL;
00054   *len = 0;
00055 
00056   for (ep = endpoints.head; ep != NULL; ep = endpoints.next(ep)) {
00057     *len += (strlen(ep->protocol) + 1);
00058   }
00059 
00060   *npn = advertised = (unsigned char *)ats_malloc(*len);
00061   if (!(*npn)) {
00062     goto fail;
00063   }
00064 
00065   for (ep = endpoints.head; ep != NULL; ep = endpoints.next(ep)) {
00066     Debug("ssl", "advertising protocol %s", ep->protocol);
00067     advertised = append_protocol(ep->protocol, advertised);
00068   }
00069 
00070   return true;
00071 
00072 fail:
00073   ats_free(*npn);
00074   *npn = NULL;
00075   *len = 0;
00076   return false;
00077 }
00078 
00079 bool
00080 SSLNextProtocolSet::advertiseProtocols(const unsigned char ** out, unsigned * len) const
00081 {
00082   if (npn && npnsz) {
00083     *out = npn;
00084     *len = npnsz;
00085     return true;
00086   }
00087 
00088   return false;
00089 }
00090 
00091 bool
00092 SSLNextProtocolSet::registerEndpoint(const char * proto, Continuation * ep)
00093 {
00094   size_t len = strlen(proto);
00095 
00096   
00097   if (len > 255) {
00098     return false;
00099   }
00100 
00101   if (!findEndpoint((const unsigned char *)proto, len)) {
00102     this->endpoints.push(new NextProtocolEndpoint(proto, ep));
00103 
00104     if (npn) {
00105       ats_free(npn);
00106       npn = NULL;
00107       npnsz = 0;
00108     }
00109 
00110     create_npn_advertisement(this->endpoints, &npn, &npnsz);
00111 
00112     return true;
00113   }
00114 
00115   return false;
00116 }
00117 
00118 bool
00119 SSLNextProtocolSet::unregisterEndpoint(const char * proto, Continuation * ep)
00120 {
00121 
00122   for (NextProtocolEndpoint * e = this->endpoints.head;
00123         e; e = this->endpoints.next(e)) {
00124     if (strcmp(proto, e->protocol) == 0 && e->endpoint == ep) {
00125       
00126       
00127       this->endpoints.remove(e);
00128       return true;
00129     }
00130   }
00131 
00132   return false;
00133 }
00134 
00135 Continuation *
00136 SSLNextProtocolSet::findEndpoint(
00137   const unsigned char * proto, unsigned len) const
00138 {
00139   for (const NextProtocolEndpoint * ep = this->endpoints.head; ep != NULL; ep = this->endpoints.next(ep)) {
00140     size_t sz = strlen(ep->protocol);
00141     if (sz == len && memcmp(ep->protocol, proto, len) == 0) {
00142       return ep->endpoint;
00143     }
00144   }
00145   return NULL;
00146 }
00147 
00148 SSLNextProtocolSet::SSLNextProtocolSet()
00149   : npn(0), npnsz(0)
00150 {
00151 }
00152 
00153 SSLNextProtocolSet::~SSLNextProtocolSet()
00154 {
00155   ats_free(this->npn);
00156 
00157   for (NextProtocolEndpoint * ep; (ep = this->endpoints.pop());) {
00158     delete ep;
00159   }
00160 }
00161 
00162 SSLNextProtocolSet::NextProtocolEndpoint::NextProtocolEndpoint(
00163         const char * _proto, Continuation * _ep)
00164   : protocol(_proto),  endpoint(_ep)
00165 {
00166 }
00167 
00168 SSLNextProtocolSet::NextProtocolEndpoint::~NextProtocolEndpoint()
00169 {
00170 }