move `get_local_ip` out of platform-specific code (#5579)

This commit is contained in:
Maximilian Hils 2022-09-11 18:40:16 +02:00 committed by GitHub
parent f9899fdd44
commit 1054f13c13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 27 deletions

35
mitmproxy/net/local_ip.py Normal file
View File

@ -0,0 +1,35 @@
from __future__ import annotations
import socket
def get_local_ip(reachable: str = "8.8.8.8") -> str | None:
"""
Get the default local outgoing IPv4 address without sending any packets.
This will fail if the target address is known to be unreachable.
We use Google DNS's IPv4 address as the default.
"""
# https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect((reachable, 80))
return s.getsockname()[0]
except OSError:
return None
finally:
s.close()
def get_local_ip6(reachable: str = "2001:4860:4860::8888") -> str | None:
"""
Get the default local outgoing IPv6 address without sending any packets.
This will fail if the target address is known to be unreachable.
We use Google DNS's IPv6 address as the default.
"""
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
s.connect((reachable, 80))
return s.getsockname()[0]
except OSError:
return None
finally:
s.close()

View File

@ -17,6 +17,8 @@ from typing import Any, ClassVar, Optional
import pydivert
import pydivert.consts
from mitmproxy.net.local_ip import get_local_ip, get_local_ip6
REDIRECT_API_HOST = "127.0.0.1"
REDIRECT_API_PORT = 8085
@ -249,32 +251,6 @@ class TcpConnectionTable(collections.abc.Mapping):
)
def get_local_ip() -> Optional[str]:
# Auto-Detect local IP. This is required as re-injecting to 127.0.0.1 does not work.
# https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
except OSError:
return None
finally:
s.close()
def get_local_ip6(reachable: str) -> Optional[str]:
# The same goes for IPv6, with the added difficulty that .connect() fails if
# the target network is not reachable.
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
s.connect((reachable, 80))
return s.getsockname()[0]
except OSError:
return None
finally:
s.close()
class Redirect(threading.Thread):
daemon = True
windivert: pydivert.WinDivert
@ -442,7 +418,7 @@ class TransparentProxy:
)
self.ipv4_address = get_local_ip()
self.ipv6_address = get_local_ip6("2001:4860:4860::8888")
self.ipv6_address = get_local_ip6()
# print(f"IPv4: {self.ipv4_address}, IPv6: {self.ipv6_address}")
self.client_server_map = ClientServerMap()

View File

@ -0,0 +1,17 @@
from mitmproxy.net import local_ip
def test_get_local_ip():
# should never error, but may return None depending on the host OS configuration.
local_ip.get_local_ip()
local_ip.get_local_ip("0.0.0.0")
local_ip.get_local_ip("127.0.0.1")
local_ip.get_local_ip("invalid!")
def test_get_local_ip6():
# should never error, but may return None depending on the host OS configuration.
local_ip.get_local_ip6()
local_ip.get_local_ip6("::")
local_ip.get_local_ip6("::1")
local_ip.get_local_ip("invalid!")