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 }