Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
linux.py34 linesDownload Raw Back to platform
1import socket2import struct3 4# Python's socket module does not have these constants5SO_ORIGINAL_DST = 806SOL_IPV6 = 417 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-mapped17    #     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.123    if is_ipv4:24        # the struct returned here should only have 8 bytes, but invoking sock.getsockopt25        # 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, port34 
codekingpro/portable-devtools · Team Ai