A minimal implementation of proxy for outgoing connections using PySocks,
special arg --tor currently just sets host and port for the socks_proxy.
This commit is contained in:
parent
a451a255af
commit
7736846646
|
@ -5,6 +5,7 @@ import errno
|
||||||
import logging
|
import logging
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
import re
|
||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
import ssl
|
import ssl
|
||||||
|
@ -78,7 +79,9 @@ class ConnectionBase(threading.Thread):
|
||||||
self.s.settimeout(0)
|
self.s.settimeout(0)
|
||||||
if not self.server:
|
if not self.server:
|
||||||
if self.network == 'ip':
|
if self.network == 'ip':
|
||||||
self.send_queue.put(message.Version(self.host, self.port))
|
self.send_queue.put(message.Version(
|
||||||
|
('127.0.0.1' if shared.socks_proxy else self.host),
|
||||||
|
self.port))
|
||||||
else:
|
else:
|
||||||
self.send_queue.put(message.Version('127.0.0.1', 7656))
|
self.send_queue.put(message.Version('127.0.0.1', 7656))
|
||||||
while True:
|
while True:
|
||||||
|
@ -507,4 +510,44 @@ class Connection(ConnectionBase):
|
||||||
self.vectors_to_send.update(getdata.vectors)
|
self.vectors_to_send.update(getdata.vectors)
|
||||||
|
|
||||||
|
|
||||||
|
class SocksConnection(Connection):
|
||||||
|
"""The socks proxied connection"""
|
||||||
|
def _connect(self):
|
||||||
|
peer_str = '{0.host_print}:{0.port}'.format(self)
|
||||||
|
logging.debug('Connecting to %s', peer_str)
|
||||||
|
|
||||||
|
import socks
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.s = socks.create_connection(
|
||||||
|
(self.host, self.port), 30, None, socks.PROXY_TYPE_SOCKS5,
|
||||||
|
shared.socks_proxy[0], shared.socks_proxy[1], True,
|
||||||
|
None, None, None)
|
||||||
|
self.status = 'connected'
|
||||||
|
logging.debug('Established SOCKS connection to %s', peer_str)
|
||||||
|
except socket.timeout:
|
||||||
|
pass
|
||||||
|
except socks.GeneralProxyError as e:
|
||||||
|
e = e.socket_err
|
||||||
|
if isinstance(e, socket.timeout) or (
|
||||||
|
# general failure, unreachable, refused
|
||||||
|
not e.errno and re.match(r'^0x0[1,4,5].*', e.msg)
|
||||||
|
):
|
||||||
|
logcall = logging.debug
|
||||||
|
else:
|
||||||
|
logcall = logging.info
|
||||||
|
logcall('Connection to %s failed. Reason: %s', peer_str, e)
|
||||||
|
except OSError as e:
|
||||||
|
# unreachable, refused, no route
|
||||||
|
(logging.info if e.errno not in (0, 101, 111, 113)
|
||||||
|
else logging.debug)(
|
||||||
|
'Connection to %s failed. Reason: %s', peer_str, e)
|
||||||
|
except Exception:
|
||||||
|
logging.info(
|
||||||
|
'Connection to %s failed.', peer_str, exc_info=True)
|
||||||
|
|
||||||
|
if self.status != 'connected':
|
||||||
|
self.status = 'failed'
|
||||||
|
|
||||||
|
|
||||||
shared.connection = Connection
|
shared.connection = Connection
|
||||||
|
|
|
@ -8,6 +8,11 @@ import os
|
||||||
import signal
|
import signal
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
try:
|
||||||
|
import socks
|
||||||
|
except ImportError:
|
||||||
|
socks = None
|
||||||
|
|
||||||
from . import i2p, shared
|
from . import i2p, shared
|
||||||
from .advertiser import Advertiser
|
from .advertiser import Advertiser
|
||||||
from .manager import Manager
|
from .manager import Manager
|
||||||
|
@ -52,6 +57,14 @@ def parse_arguments(): # pylint: disable=too-many-branches,too-many-statements
|
||||||
'--i2p-transient', action='store_true',
|
'--i2p-transient', action='store_true',
|
||||||
help='Generate new I2P destination on start')
|
help='Generate new I2P destination on start')
|
||||||
|
|
||||||
|
if socks is not None:
|
||||||
|
parser.add_argument(
|
||||||
|
'--socks-proxy',
|
||||||
|
help='SOCKS proxy address in the form <HOST>:<PORT>')
|
||||||
|
parser.add_argument(
|
||||||
|
'--tor', action='store_true',
|
||||||
|
help='The SOCKS proxy is tor, use 127.0.0.1:9050 if not specified')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if args.port:
|
if args.port:
|
||||||
shared.listening_port = args.port
|
shared.listening_port = args.port
|
||||||
|
@ -71,7 +84,8 @@ def parse_arguments(): # pylint: disable=too-many-branches,too-many-statements
|
||||||
if args.no_ip:
|
if args.no_ip:
|
||||||
shared.ip_enabled = False
|
shared.ip_enabled = False
|
||||||
if args.trusted_peer:
|
if args.trusted_peer:
|
||||||
if len(args.trusted_peer) > 50:
|
if len(args.trusted_peer
|
||||||
|
) > 50 and not args.trusted_peer.endswith('onion'):
|
||||||
# I2P
|
# I2P
|
||||||
shared.trusted_peer = (args.trusted_peer.encode(), 'i2p')
|
shared.trusted_peer = (args.trusted_peer.encode(), 'i2p')
|
||||||
else:
|
else:
|
||||||
|
@ -99,6 +113,16 @@ def parse_arguments(): # pylint: disable=too-many-branches,too-many-statements
|
||||||
if args.i2p_transient:
|
if args.i2p_transient:
|
||||||
shared.i2p_transient = True
|
shared.i2p_transient = True
|
||||||
|
|
||||||
|
if socks is None:
|
||||||
|
return
|
||||||
|
if args.tor:
|
||||||
|
shared.tor = True
|
||||||
|
if not args.socks_proxy:
|
||||||
|
shared.socks_proxy = ('127.0.0.1', 9050)
|
||||||
|
if args.socks_proxy:
|
||||||
|
addr = args.socks_proxy.split(':')
|
||||||
|
shared.socks_proxy = (addr[0], int(addr[1]))
|
||||||
|
|
||||||
|
|
||||||
def bootstrap_from_dns():
|
def bootstrap_from_dns():
|
||||||
"""Addes addresses of bootstrap servers to known nodes"""
|
"""Addes addresses of bootstrap servers to known nodes"""
|
||||||
|
|
|
@ -11,7 +11,7 @@ import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from . import proofofwork, shared, structure
|
from . import proofofwork, shared, structure
|
||||||
from .connection import Connection
|
from .connection import Connection, SocksConnection
|
||||||
from .i2p import I2PDialer
|
from .i2p import I2PDialer
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,7 +142,8 @@ class Manager(threading.Thread):
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
c = Connection(host, port)
|
c = (Connection if not shared.socks_proxy
|
||||||
|
else SocksConnection)(host, port)
|
||||||
c.start()
|
c.start()
|
||||||
hosts.add(group)
|
hosts.add(group)
|
||||||
with shared.connections_lock:
|
with shared.connections_lock:
|
||||||
|
@ -190,7 +191,7 @@ class Manager(threading.Thread):
|
||||||
'r', newline='', encoding='ascii'
|
'r', newline='', encoding='ascii'
|
||||||
) as src:
|
) as src:
|
||||||
reader = csv.reader(src)
|
reader = csv.reader(src)
|
||||||
shared.core_nodes = {tuple(row) for row in reader}
|
shared.core_nodes = {(row[0], int(row[1])) for row in reader}
|
||||||
shared.node_pool.update(shared.core_nodes)
|
shared.node_pool.update(shared.core_nodes)
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
|
|
|
@ -27,6 +27,9 @@ header_length = 24
|
||||||
i2p_dest_obj_type = 0x493250
|
i2p_dest_obj_type = 0x493250
|
||||||
i2p_dest_obj_version = 1
|
i2p_dest_obj_version = 1
|
||||||
|
|
||||||
|
socks_proxy = None
|
||||||
|
tor = False
|
||||||
|
|
||||||
i2p_enabled = False
|
i2p_enabled = False
|
||||||
i2p_transient = False
|
i2p_transient = False
|
||||||
i2p_sam_host = '127.0.0.1'
|
i2p_sam_host = '127.0.0.1'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user