Add transparent mode platform module for Linux.

This commit is contained in:
Aldo Cortesi 2012-06-26 20:49:34 +12:00
parent ad893ad134
commit e6cdbefb3b
3 changed files with 32 additions and 5 deletions

View File

@ -0,0 +1,7 @@
import sys
resolver = None
if sys.platform == "linux2":
import linux
resolver = linux.Resolver()

View File

@ -0,0 +1,11 @@
import socket, struct
# Python socket module does not have this constant
SO_ORIGINAL_DST = 80
class Resolver:
def original_addr(self, csock):
odestdata = csock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)
_, port, a1, a2, a3, a4 = struct.unpack("!HHBBBBxxxxxxxx", odestdata)
address = "%d.%d.%d.%d" % (a1, a2, a3, a4)
return address, port

View File

@ -17,7 +17,7 @@ import shutil, tempfile, threading
import optparse, SocketServer import optparse, SocketServer
from OpenSSL import SSL from OpenSSL import SSL
from netlib import odict, tcp, http, wsgi from netlib import odict, tcp, http, wsgi
import utils, flow, certutils, version import utils, flow, certutils, version, platform
class ProxyError(Exception): class ProxyError(Exception):
@ -222,7 +222,10 @@ class ProxyHandler(tcp.BaseHandler):
self.convert_to_ssl(certfile, self.config.certfile or self.config.cacert) self.convert_to_ssl(certfile, self.config.certfile or self.config.cacert)
else: else:
scheme = "http" scheme = "http"
method, path, httpversion = http.parse_init_http(line) r = http.parse_init_http(line)
if not r:
raise ProxyError(400, "Bad HTTP request line.")
method, path, httpversion = r
headers = http.read_headers(self.rfile) headers = http.read_headers(self.rfile)
content = http.read_http_body_request( content = http.read_http_body_request(
self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit
@ -230,7 +233,10 @@ class ProxyHandler(tcp.BaseHandler):
return flow.Request(client_conn, httpversion, host, port, "http", method, path, headers, content) return flow.Request(client_conn, httpversion, host, port, "http", method, path, headers, content)
elif self.config.reverse_proxy: elif self.config.reverse_proxy:
scheme, host, port = self.config.reverse_proxy scheme, host, port = self.config.reverse_proxy
method, path, httpversion = http.parse_init_http(line) r = http.parse_init_http(line)
if not r:
raise ProxyError(400, "Bad HTTP request line.")
method, path, httpversion = r
headers = http.read_headers(self.rfile) headers = http.read_headers(self.rfile)
content = http.read_http_body_request( content = http.read_http_body_request(
self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit
@ -257,7 +263,10 @@ class ProxyHandler(tcp.BaseHandler):
line = self.rfile.readline(line) line = self.rfile.readline(line)
if self.proxy_connect_state: if self.proxy_connect_state:
host, port, httpversion = self.proxy_connect_state host, port, httpversion = self.proxy_connect_state
method, path, httpversion = http.parse_init_http(line) r = http.parse_init_http(line)
if not r:
raise ProxyError(400, "Bad HTTP request line.")
method, path, httpversion = r
headers = http.read_headers(self.rfile) headers = http.read_headers(self.rfile)
content = http.read_http_body_request( content = http.read_http_body_request(
self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit self.rfile, self.wfile, headers, httpversion, self.config.body_size_limit
@ -400,7 +409,7 @@ def process_proxy_options(parser, options):
if options.transparent_proxy: if options.transparent_proxy:
trans = dict( trans = dict(
resolver = None, resolver = platform.resolver,
sslports = TRANSPARENT_SSL_PORTS sslports = TRANSPARENT_SSL_PORTS
) )
else: else: