MCPcopy Index your code
hub / github.com/mitmproxy/mitmproxy / original_addr

Function original_addr

mitmproxy/platform/linux.py:9–33  ·  view source on GitHub ↗
(csock: socket.socket)

Source from the content-addressed store, hash-verified

7
8
9def original_addr(csock: socket.socket) -> tuple[str, int]:
10 # Get the original destination on Linux.
11 # In theory, this can be done using the following syscalls:
12 # sock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)
13 # sock.getsockopt(SOL_IPV6, SO_ORIGINAL_DST, 28)
14 #
15 # In practice, it is a bit more complex:
16 # 1. We cannot rely on sock.family to decide which syscall to use because of IPv4-mapped
17 # IPv6 addresses. If sock.family is AF_INET6 while sock.getsockname() is ::ffff:127.0.0.1,
18 # we need to call the IPv4 version to get a result.
19 # 2. We can't just try the IPv4 syscall and then do IPv6 if that doesn't work,
20 # because doing the wrong syscall can apparently crash the whole Python runtime.
21 # As such, we use a heuristic to check which syscall to do.
22 is_ipv4 = "." in csock.getsockname()[0] # either 127.0.0.1 or ::ffff:127.0.0.1
23 if is_ipv4:
24 # the struct returned here should only have 8 bytes, but invoking sock.getsockopt
25 # with buflen=8 doesn't work.
26 dst = csock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)
27 port, raw_ip = struct.unpack_from("!2xH4s", dst)
28 ip = socket.inet_ntop(socket.AF_INET, raw_ip)
29 else:
30 dst = csock.getsockopt(SOL_IPV6, SO_ORIGINAL_DST, 28)
31 port, raw_ip = struct.unpack_from("!2xH4x16s", dst)
32 ip = socket.inet_ntop(socket.AF_INET6, raw_ip)
33 return ip, port

Callers

nothing calls this directly

Calls 1

unpack_fromMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…