Support dual stack listening
This commit is contained in:
parent
439d2bcf7f
commit
1824363f86
5 changed files with 58 additions and 34 deletions
|
@ -51,6 +51,7 @@ class ConfigStorage extends Class
|
|||
options: [
|
||||
{title: "IPv4", value: "ipv4"}
|
||||
{title: "IPv6", value: "ipv6"}
|
||||
{title: "Dual (IPv4 & IPv6)", value: "dual"}
|
||||
]
|
||||
description: "Accept incoming peers using IPv4 or IPv6 address. (default: IPv4)"
|
||||
|
||||
|
|
|
@ -1367,7 +1367,7 @@
|
|||
value: "ipv6"
|
||||
}
|
||||
],
|
||||
description: "Accept other peers using IPv4 or IPv6 address. (default: IPv4)"
|
||||
description: "Accept incoming peers using IPv4 or IPv6 address. (default: IPv4)"
|
||||
});
|
||||
section.items.push({
|
||||
key: "fileserver_port",
|
||||
|
|
|
@ -237,7 +237,7 @@ class Config(object):
|
|||
self.parser.add_argument('--fileserver_ip', help='FileServer bind address', default="*", metavar='ip')
|
||||
self.parser.add_argument('--fileserver_port', help='FileServer bind port (0: randomize)', default=0, type=int, metavar='port')
|
||||
self.parser.add_argument('--fileserver_port_range', help='FileServer randomization range', default="10000-40000", metavar='port')
|
||||
self.parser.add_argument('--fileserver_ip_type', help='FileServer ip type', default="ipv4", choices=["ipv4", "ipv6"])
|
||||
self.parser.add_argument('--fileserver_ip_type', help='FileServer ip type', default="dual", choices=["ipv4", "ipv6", "dual"])
|
||||
self.parser.add_argument('--ip_local', help='My local ips', default=ip_local, type=int, metavar='ip', nargs='*')
|
||||
|
||||
self.parser.add_argument('--disable_udp', help='Disable UDP connections', action='store_true')
|
||||
|
|
|
@ -32,7 +32,7 @@ class ConnectionServer(object):
|
|||
self.port = port
|
||||
self.last_connection_id = 1 # Connection id incrementer
|
||||
self.log = logging.getLogger("ConnServer")
|
||||
self.port_opened = None
|
||||
self.port_opened = {}
|
||||
self.peer_blacklist = SiteManager.peer_blacklist
|
||||
|
||||
self.tor_manager = TorManager(self.ip, self.port)
|
||||
|
@ -42,11 +42,9 @@ class ConnectionServer(object):
|
|||
self.broken_ssl_ips = {} # Peerids of broken ssl connections
|
||||
self.ips = {} # Connection by ip
|
||||
self.has_internet = True # Internet outage detection
|
||||
self.supported_ip_types = ["ipv4"] # Outgoing ip_type support
|
||||
if self.isIpv6Supported():
|
||||
self.supported_ip_types.append("ipv6")
|
||||
|
||||
self.stream_server = None
|
||||
self.stream_server_proxy = None
|
||||
self.running = False
|
||||
|
||||
self.stat_recv = defaultdict(lambda: defaultdict(int))
|
||||
|
@ -61,6 +59,7 @@ class ConnectionServer(object):
|
|||
self.had_external_incoming = False
|
||||
|
||||
self.timecorrection = 0.0
|
||||
self.pool = Pool(500) # do not accept more than 500 connections
|
||||
|
||||
# Bittorrent style peerid
|
||||
self.peer_id = "-UT3530-%s" % CryptHash.random(12, "base64")
|
||||
|
@ -92,36 +91,15 @@ class ConnectionServer(object):
|
|||
CryptConnection.manager.crypt_supported, self.supported_ip_types
|
||||
))
|
||||
try:
|
||||
self.pool = Pool(500) # do not accept more than 500 connections
|
||||
if helper.getIpType(self.ip) == "ipv6":
|
||||
sock_address = (self.ip, self.port, 0, 0)
|
||||
else:
|
||||
sock_address = (self.ip, self.port)
|
||||
|
||||
self.stream_server = StreamServer(
|
||||
sock_address, self.handleIncomingConnection, spawn=self.pool, backlog=100
|
||||
(self.ip, self.port), self.handleIncomingConnection, spawn=self.pool, backlog=100
|
||||
)
|
||||
except Exception, err:
|
||||
self.log.info("StreamServer bind error: %s" % err)
|
||||
|
||||
def isIpv6Supported(self):
|
||||
if helper.getIpType(self.ip) == "ipv6":
|
||||
return True
|
||||
|
||||
# Test if we can connect to ipv6 address
|
||||
ipv6_testip = "2001:19f0:6c01:e76:5400:1ff:fed6:3eca"
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
sock.connect((ipv6_testip, 80))
|
||||
local_ipv6 = sock.getsockname()[0]
|
||||
if local_ipv6 == "::1":
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
except Exception as err:
|
||||
return False
|
||||
self.log.info("StreamServer create error: %s" % Debug.formatException(err))
|
||||
|
||||
def listen(self):
|
||||
if self.stream_server_proxy:
|
||||
gevent.spawn(self.listenProxy)
|
||||
try:
|
||||
self.stream_server.serve_forever()
|
||||
except Exception, err:
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import logging
|
||||
import time
|
||||
import random
|
||||
import socket
|
||||
|
||||
import gevent
|
||||
import gevent.pool
|
||||
from gevent.server import StreamServer
|
||||
|
||||
import util
|
||||
from util import helper
|
||||
|
@ -13,6 +15,7 @@ from Peer import PeerPortchecker
|
|||
from Site import SiteManager
|
||||
from Connection import ConnectionServer
|
||||
from Plugin import PluginManager
|
||||
from Debug import Debug
|
||||
|
||||
|
||||
@PluginManager.acceptPlugins
|
||||
|
@ -23,7 +26,12 @@ class FileServer(ConnectionServer):
|
|||
self.portchecker = PeerPortchecker.PeerPortchecker(self)
|
||||
self.log = logging.getLogger("FileServer")
|
||||
self.ip_type = ip_type
|
||||
if ip_type == "ipv6":
|
||||
|
||||
self.supported_ip_types = ["ipv4"] # Outgoing ip_type support
|
||||
if helper.getIpType(ip) == "ipv6" or self.isIpv6Supported():
|
||||
self.supported_ip_types.append("ipv6")
|
||||
|
||||
if ip_type == "ipv6" or (ip_type == "dual" and "ipv6" in self.supported_ip_types):
|
||||
ip = ip.replace("*", "::")
|
||||
else:
|
||||
ip = ip.replace("*", "0.0.0.0")
|
||||
|
@ -42,14 +50,22 @@ class FileServer(ConnectionServer):
|
|||
|
||||
ConnectionServer.__init__(self, ip, port, self.handleRequest)
|
||||
|
||||
if ip_type == "dual" and ip == "::":
|
||||
# Also bind to ipv4 addres in dual mode
|
||||
try:
|
||||
self.log.debug("Binding proxy to %s:%s" % ("::", self.port))
|
||||
self.stream_server_proxy = StreamServer(
|
||||
("0.0.0.0", self.port), self.handleIncomingConnection, spawn=self.pool, backlog=100
|
||||
)
|
||||
except Exception, err:
|
||||
self.log.info("StreamServer proxy create error: %s" % Debug.formatException(err))
|
||||
|
||||
self.port_opened = {}
|
||||
|
||||
if config.ip_external: # Ip external defined in arguments
|
||||
self.port_opened[helper.getIpType(config.ip_external)] = True
|
||||
SiteManager.peer_blacklist.append((config.ip_external, self.port)) # Add myself to peer blacklist
|
||||
else:
|
||||
self.port_opened = None # Check it later
|
||||
|
||||
self.sites = {}
|
||||
self.last_request = time.time()
|
||||
self.files_parsing = {}
|
||||
|
@ -78,6 +94,35 @@ class FileServer(ConnectionServer):
|
|||
time.sleep(0.1)
|
||||
return False
|
||||
|
||||
def isIpv6Supported(self):
|
||||
# Test if we can connect to ipv6 address
|
||||
ipv6_testip = "2001:19f0:6c01:e76:5400:1ff:fed6:3eca"
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
||||
sock.connect((ipv6_testip, 80))
|
||||
local_ipv6 = sock.getsockname()[0]
|
||||
if local_ipv6 == "::1":
|
||||
self.log.debug("IPv6 not supported, no local IPv6 address")
|
||||
return False
|
||||
else:
|
||||
self.log.debug("IPv6 supported on IP %s" % local_ipv6)
|
||||
return True
|
||||
except socket.error as err:
|
||||
self.log.error("IPv6 not supported: %s" % err)
|
||||
return False
|
||||
except Exception as err:
|
||||
self.log.error("IPv6 check error: %s" % err)
|
||||
return False
|
||||
|
||||
def listenProxy(self):
|
||||
try:
|
||||
self.stream_server_proxy.serve_forever()
|
||||
except Exception, err:
|
||||
if err.errno == 98: # Address already in use error
|
||||
self.log.debug("StreamServer proxy listen error: %s" % err)
|
||||
else:
|
||||
self.log.info("StreamServer proxy listen error: %s" % err)
|
||||
|
||||
# Handle request to fileserver
|
||||
def handleRequest(self, connection, message):
|
||||
if config.verbose:
|
||||
|
|
Loading…
Reference in a new issue