-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconnection_errors.py
More file actions
116 lines (105 loc) · 6.05 KB
/
Copy pathconnection_errors.py
File metadata and controls
116 lines (105 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# connection_errors.py
def describe_unexpected_packet(info_message):
"""Return a user-friendly explanation for unexpected packet flows."""
if info_message == "unexpected inbound packet":
return (
"The destination replied with a packet that does not match the expected flow for this bypass method. "
"This usually means the active IP or route is no longer suitable."
)
if info_message == "unexpected inbound packet, no syn sent!":
return (
"The received packet does not match the current connection state and arrived before the SYN was tracked. "
"The network path is likely unstable or packets arrived out of order."
)
if "seq not matched" in info_message or "ack not matched" in info_message:
return (
"The network response did not match the expected ACK/SEQ numbers. "
"This usually points to route instability, different server behavior, or an invalid active IP."
)
if "unexpected outbound packet" in info_message:
return (
"While creating the connection, the app emitted a packet that did not match the expected flow. "
"This attempt was stopped to avoid compounding the failure."
)
return f"Received an unexpected packet flow: {info_message}"
def describe_socket_not_ready_error(destination_ip, destination_port, close_reason=None):
"""Explain WinError 10038 using the most relevant prior close reason."""
destination_label = f"{destination_ip}:{destination_port}"
if close_reason:
return (
f"The connection to {destination_label} closed before the handshake finished. "
f"{close_reason}"
)
return (
f"The connection to {destination_label} was not ready before the socket closed "
f"(WinError 10038). This usually happens after an incompatible network response."
)
def describe_operation_aborted_error(destination_ip, destination_port, close_reason=None):
"""Explain WinError 995 in terms of the earlier network event that aborted the socket."""
destination_label = f"{destination_ip}:{destination_port}"
if close_reason:
return (
f"The app aborted the attempt to connect to {destination_label} because "
f"the network returned an incompatible response. {close_reason}"
)
return (
f"Windows aborted the attempt to connect to {destination_label} "
f"(WinError 995). This usually happens when the socket is intentionally closed mid-flight."
)
def describe_runtime_socket_error(error, connection_label="current connection"):
"""Return a user-friendly explanation for runtime socket errors."""
if isinstance(error, OSError):
winerror = getattr(error, "winerror", None)
if winerror == 10054:
return (
f"{connection_label} was closed unexpectedly by the remote side "
f"(Connection reset / WinError 10054). This usually means the destination, "
f"the intermediate path, or the user's network interrupted the flow. "
f"If it keeps happening, the active IP or route is likely unstable."
)
if winerror == 10060:
return (
f"{connection_label} did not complete because the network timed out "
f"(Connection timed out / WinError 10060). This usually points to a slow or unstable path."
)
if winerror == 64:
return f"{connection_label} became unavailable mid-stream (WinError 64)."
return f"{connection_label} stopped with an error: {error}"
def describe_connect_error(destination_ip, destination_port, error):
"""Return a user-friendly explanation for outbound connection failures."""
destination_label = f"{destination_ip}:{destination_port}"
if isinstance(error, TimeoutError):
return (
f"The connection to {destination_label} did not answer before the timeout. "
"This usually points to network delay, route instability, or an unavailable active IP. "
"If it keeps happening, the app first holds the current route and only re-scans when the disruption persists."
)
if isinstance(error, OSError):
winerror = getattr(error, "winerror", None)
if winerror == 121:
return (
f"The connection to {destination_label} stalled because the network was too slow or the path stopped responding "
f"(Windows timeout / WinError 121). This is usually temporary and can come from internet instability, "
f"Cloudflare path issues, or an expired active IP. The app will keep the same route for several waves before re-scanning."
)
if winerror == 10060:
return (
f"The connection to {destination_label} timed out and the destination did not respond in time. "
"The current IP may no longer be suitable, or the route may be unstable. "
"The app first tries to keep the same route and only re-scans after repeated failures."
)
if winerror == 10054:
return (
f"The connection to {destination_label} was reset unexpectedly by the remote side "
f"(Connection reset / WinError 10054). This usually means the active IP or current path "
f"is no longer stable. The app only scans for a new route after several failure waves."
)
if winerror == 1232:
return (
f"The connection to {destination_label} could not be reached because Windows reports the network location is unavailable "
f"(WinError 1232). This usually means the local interface, gateway, or current route disappeared temporarily. "
f"The app will keep the current route for a while, but if the outage persists it will scan again."
)
if winerror == 995:
return describe_operation_aborted_error(destination_ip, destination_port)
return f"Connection error while reaching {destination_label}: {error}"