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 }