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 "P_Net.h"
00026 #include "Main.h"
00027 #include "Error.h"
00028 #include "HttpConfig.h"
00029 #include "HttpSessionAccept.h"
00030 #include "ReverseProxy.h"
00031 #include "HttpSessionManager.h"
00032 #include "HttpUpdateSM.h"
00033 #include "HttpClientSession.h"
00034 #include "HttpPages.h"
00035 #include "HttpTunnel.h"
00036 #include "Tokenizer.h"
00037 #include "P_SSLNextProtocolAccept.h"
00038 #include "ProtocolProbeSessionAccept.h"
00039 #include "SpdySessionAccept.h"
00040 #include "http2/Http2SessionAccept.h"
00041
00042 HttpSessionAccept *plugin_http_accept = NULL;
00043 HttpSessionAccept *plugin_http_transparent_accept = 0;
00044
00045 static SLL<SSLNextProtocolAccept> ssl_plugin_acceptors;
00046 static ink_mutex ssl_plugin_mutex = PTHREAD_MUTEX_INITIALIZER;
00047
00048 bool
00049 ssl_register_protocol(const char * protocol, Continuation * contp)
00050 {
00051 ink_scoped_mutex lock(ssl_plugin_mutex);
00052
00053 for (SSLNextProtocolAccept * ssl = ssl_plugin_acceptors.head;
00054 ssl; ssl = ssl_plugin_acceptors.next(ssl)) {
00055 if (!ssl->registerEndpoint(protocol, contp)) {
00056 return false;
00057 }
00058 }
00059
00060 return true;
00061 }
00062
00063 bool
00064 ssl_unregister_protocol(const char * protocol, Continuation * contp)
00065 {
00066 ink_scoped_mutex lock(ssl_plugin_mutex);
00067
00068 for (SSLNextProtocolAccept * ssl = ssl_plugin_acceptors.head;
00069 ssl; ssl = ssl_plugin_acceptors.next(ssl)) {
00070
00071
00072 ssl->unregisterEndpoint(protocol, contp);
00073 }
00074
00075 return true;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 struct HttpProxyAcceptor {
00091
00092 Continuation* _accept;
00093
00094 NetProcessor::AcceptOptions _net_opt;
00095
00096
00097 HttpProxyAcceptor()
00098 : _accept(0)
00099 {
00100 }
00101 };
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 Vec<HttpProxyAcceptor> HttpProxyAcceptors;
00113
00114
00115 NetProcessor::AcceptOptions
00116 make_net_accept_options(const HttpProxyPort& port, unsigned nthreads)
00117 {
00118 NetProcessor::AcceptOptions net;
00119
00120 net.accept_threads = nthreads;
00121
00122 net.f_inbound_transparent = port.m_inbound_transparent_p;
00123 net.ip_family = port.m_family;
00124 net.local_port = port.m_port;
00125
00126 if (port.m_inbound_ip.isValid()) {
00127 net.local_ip = port.m_inbound_ip;
00128 } else if (AF_INET6 == port.m_family && HttpConfig::m_master.inbound_ip6.isIp6()) {
00129 net.local_ip = HttpConfig::m_master.inbound_ip6;
00130 } else if (AF_INET == port.m_family && HttpConfig::m_master.inbound_ip4.isIp4()) {
00131 net.local_ip = HttpConfig::m_master.inbound_ip4;
00132 }
00133
00134 return net;
00135 }
00136
00137 static void
00138 MakeHttpProxyAcceptor(HttpProxyAcceptor& acceptor, HttpProxyPort& port, unsigned nthreads)
00139 {
00140 NetProcessor::AcceptOptions& net_opt = acceptor._net_opt;
00141 HttpSessionAccept::Options accept_opt;
00142
00143 net_opt = make_net_accept_options(port, nthreads);
00144 REC_ReadConfigInteger(net_opt.recv_bufsize, "proxy.config.net.sock_recv_buffer_size_in");
00145 REC_ReadConfigInteger(net_opt.send_bufsize, "proxy.config.net.sock_send_buffer_size_in");
00146 REC_ReadConfigInteger(net_opt.packet_mark, "proxy.config.net.sock_packet_mark_in");
00147 REC_ReadConfigInteger(net_opt.packet_tos, "proxy.config.net.sock_packet_tos_in");
00148
00149 accept_opt.f_outbound_transparent = port.m_outbound_transparent_p;
00150 accept_opt.transport_type = port.m_type;
00151 accept_opt.setHostResPreference(port.m_host_res_preference);
00152 accept_opt.setTransparentPassthrough(port.m_transparent_passthrough);
00153 accept_opt.setSessionProtocolPreference(port.m_session_protocol_preference);
00154
00155 if (port.m_outbound_ip4.isValid()) {
00156 accept_opt.outbound_ip4 = port.m_outbound_ip4;
00157 } else if (HttpConfig::m_master.outbound_ip4.isValid()) {
00158 accept_opt.outbound_ip4 = HttpConfig::m_master.outbound_ip4;
00159 }
00160
00161 if (port.m_outbound_ip6.isValid()) {
00162 accept_opt.outbound_ip6 = port.m_outbound_ip6;
00163 } else if (HttpConfig::m_master.outbound_ip6.isValid()) {
00164 accept_opt.outbound_ip6 = HttpConfig::m_master.outbound_ip6;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 ProtocolProbeSessionAccept *probe = new ProtocolProbeSessionAccept();
00175 HttpSessionAccept *http = 0;
00176
00177 if (port.m_session_protocol_preference.intersects(HTTP_PROTOCOL_SET)) {
00178 http = new HttpSessionAccept(accept_opt);
00179 probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_HTTP, http);
00180 }
00181
00182 #if TS_HAS_SPDY
00183 if (port.m_session_protocol_preference.intersects(SPDY_PROTOCOL_SET)) {
00184 probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_SPDY, new SpdySessionAccept(spdy::SESSION_VERSION_3_1));
00185 }
00186 #endif
00187
00188 if (port.m_session_protocol_preference.intersects(HTTP2_PROTOCOL_SET)) {
00189 probe->registerEndpoint(ProtocolProbeSessionAccept::PROTO_HTTP2, new Http2SessionAccept(accept_opt));
00190 }
00191
00192 if (port.isSSL()) {
00193 SSLNextProtocolAccept *ssl = new SSLNextProtocolAccept(probe);
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if (port.m_session_protocol_preference.contains(TS_NPN_PROTOCOL_INDEX_HTTP_1_0)) {
00204 ssl->registerEndpoint(TS_NPN_PROTOCOL_HTTP_1_0, http);
00205 }
00206
00207 if (port.m_session_protocol_preference.contains(TS_NPN_PROTOCOL_INDEX_HTTP_1_1)) {
00208 ssl->registerEndpoint(TS_NPN_PROTOCOL_HTTP_1_1, http);
00209 }
00210
00211
00212 if (port.m_session_protocol_preference.contains(TS_NPN_PROTOCOL_INDEX_HTTP_2_0)) {
00213 ssl->registerEndpoint(TS_NPN_PROTOCOL_HTTP_2_0, new Http2SessionAccept(accept_opt));
00214 }
00215
00216
00217 #if TS_HAS_SPDY
00218 if (port.m_session_protocol_preference.contains(TS_NPN_PROTOCOL_INDEX_SPDY_3)) {
00219 ssl->registerEndpoint(TS_NPN_PROTOCOL_SPDY_3, new SpdySessionAccept(spdy::SESSION_VERSION_3));
00220 }
00221
00222 if (port.m_session_protocol_preference.contains(TS_NPN_PROTOCOL_INDEX_SPDY_3_1)) {
00223 ssl->registerEndpoint(TS_NPN_PROTOCOL_SPDY_3_1, new SpdySessionAccept(spdy::SESSION_VERSION_3_1));
00224 }
00225 #endif
00226
00227 ink_scoped_mutex lock(ssl_plugin_mutex);
00228 ssl_plugin_acceptors.push(ssl);
00229
00230 acceptor._accept = ssl;
00231 } else {
00232 acceptor._accept = probe;
00233 }
00234 }
00235
00236
00237
00238 void
00239 init_HttpProxyServer(int n_accept_threads)
00240 {
00241 HttpProxyPort::Group& proxy_ports = HttpProxyPort::global();
00242
00243 init_reverse_proxy();
00244 httpSessionManager.init();
00245 http_pages_init();
00246 ink_mutex_init(&debug_sm_list_mutex, "HttpSM Debug List");
00247 ink_mutex_init(&debug_cs_list_mutex, "HttpCS Debug List");
00248
00249 icp_dynamic_enabled = 1;
00250
00251
00252
00253
00254
00255 if (plugin_http_accept == NULL) {
00256 plugin_http_accept = new HttpSessionAccept;
00257 plugin_http_accept->mutex = new_ProxyMutex();
00258 }
00259
00260 if (! plugin_http_transparent_accept) {
00261 HttpSessionAccept::Options ha_opt;
00262 ha_opt.setOutboundTransparent(true);
00263 plugin_http_transparent_accept = new HttpSessionAccept(ha_opt);
00264 plugin_http_transparent_accept->mutex = new_ProxyMutex();
00265 }
00266 ink_mutex_init(&ssl_plugin_mutex, "SSL Acceptor List");
00267
00268
00269 for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
00270 MakeHttpProxyAcceptor(HttpProxyAcceptors.add(), proxy_ports[i], n_accept_threads);
00271 }
00272
00273 }
00274
00275 void
00276 start_HttpProxyServer()
00277 {
00278 static bool called_once = false;
00279 HttpProxyPort::Group& proxy_ports = HttpProxyPort::global();
00280
00281
00282
00283
00284
00285 ink_assert(!called_once);
00286 ink_assert(proxy_ports.length() == HttpProxyAcceptors.length());
00287
00288 for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
00289 HttpProxyAcceptor& acceptor = HttpProxyAcceptors[i];
00290 HttpProxyPort& port = proxy_ports[i];
00291 if (port.isSSL()) {
00292 if (NULL == sslNetProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt))
00293 return;
00294 } else if (! port.isPlugin()) {
00295 if (NULL == netProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt))
00296 return;
00297 }
00298
00299
00300 }
00301
00302 #if TS_HAS_TESTS
00303 if (is_action_tag_set("http_update_test")) {
00304 init_http_update_test();
00305 }
00306 #endif
00307
00308
00309 APIHook* hook = lifecycle_hooks->get(TS_LIFECYCLE_PORTS_READY_HOOK);
00310 while (hook) {
00311 hook->invoke(TS_EVENT_LIFECYCLE_PORTS_READY, NULL);
00312 hook = hook->next();
00313 }
00314
00315 }
00316
00317 void
00318 start_HttpProxyServerBackDoor(int port, int accept_threads)
00319 {
00320 NetProcessor::AcceptOptions opt;
00321 HttpSessionAccept::Options ha_opt;
00322
00323 opt.local_port = port;
00324 opt.accept_threads = accept_threads;
00325 opt.localhost_only = true;
00326 ha_opt.backdoor = true;
00327 opt.backdoor = true;
00328
00329
00330 netProcessor.main_accept(new HttpSessionAccept(ha_opt), NO_FD, opt);
00331 }