Move _fixSocket from bitmessagemain to helper_startup,

so it can be used in test_networkgroup.
This commit is contained in:
Dmitri Bogomolov 2020-02-20 15:09:52 +02:00
parent 568c0a606f
commit 083451c8ac
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
3 changed files with 73 additions and 66 deletions

View File

@ -21,16 +21,13 @@ app_dir = pathmagic.setup()
import depends import depends
depends.check_dependencies() depends.check_dependencies()
import ctypes
import getopt import getopt
import multiprocessing import multiprocessing
# Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully. # Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully.
import signal import signal
import socket
import threading import threading
import time import time
import traceback import traceback
from struct import pack
import defaults import defaults
import shared import shared
@ -39,7 +36,7 @@ import state
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from debug import logger # this should go before any threads from debug import logger # this should go before any threads
from helper_startup import ( from helper_startup import (
adjustHalfOpenConnectionsLimit, start_proxyconfig) adjustHalfOpenConnectionsLimit, fixSocket, start_proxyconfig)
from inventory import Inventory from inventory import Inventory
# Network objects and threads # Network objects and threads
from network import ( from network import (
@ -54,67 +51,6 @@ from threads import (
addressGenerator, objectProcessor, singleCleaner, singleWorker, sqlThread) addressGenerator, objectProcessor, singleCleaner, singleWorker, sqlThread)
def _fixSocket():
if sys.platform.startswith('linux'):
socket.SO_BINDTODEVICE = 25
if not sys.platform.startswith('win'):
return
# Python 2 on Windows doesn't define a wrapper for
# socket.inet_ntop but we can make one ourselves using ctypes
if not hasattr(socket, 'inet_ntop'):
addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
def inet_ntop(family, host):
"""Converting an IP address in packed
binary format to string format"""
if family == socket.AF_INET:
if len(host) != 4:
raise ValueError("invalid IPv4 host")
host = pack("hH4s8s", socket.AF_INET, 0, host, "\0" * 8)
elif family == socket.AF_INET6:
if len(host) != 16:
raise ValueError("invalid IPv6 host")
host = pack("hHL16sL", socket.AF_INET6, 0, 0, host, 0)
else:
raise ValueError("invalid address family")
buf = "\0" * 64
lengthBuf = pack("I", len(buf))
addressToString(host, len(host), None, buf, lengthBuf)
return buf[0:buf.index("\0")]
socket.inet_ntop = inet_ntop
# Same for inet_pton
if not hasattr(socket, 'inet_pton'):
stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
def inet_pton(family, host):
"""Converting an IP address in string format
to a packed binary format"""
buf = "\0" * 28
lengthBuf = pack("I", len(buf))
if stringToAddress(str(host),
int(family),
None,
buf,
lengthBuf) != 0:
raise socket.error("illegal IP address passed to inet_pton")
if family == socket.AF_INET:
return buf[4:8]
elif family == socket.AF_INET6:
return buf[8:24]
else:
raise ValueError("invalid address family")
socket.inet_pton = inet_pton
# These sockopts are needed on for IPv6 support
if not hasattr(socket, 'IPPROTO_IPV6'):
socket.IPPROTO_IPV6 = 41
if not hasattr(socket, 'IPV6_V6ONLY'):
socket.IPV6_V6ONLY = 27
def signal_handler(signum, frame): def signal_handler(signum, frame):
"""Single handler for any signal sent to pybitmessage""" """Single handler for any signal sent to pybitmessage"""
process = multiprocessing.current_process() process = multiprocessing.current_process()
@ -151,7 +87,7 @@ class Main(object):
def start(self): def start(self):
"""Start main application""" """Start main application"""
# pylint: disable=too-many-statements,too-many-branches,too-many-locals # pylint: disable=too-many-statements,too-many-branches,too-many-locals
_fixSocket() fixSocket()
adjustHalfOpenConnectionsLimit() adjustHalfOpenConnectionsLimit()
config = BMConfigParser() config = BMConfigParser()

View File

@ -3,12 +3,15 @@ Startup operations.
""" """
# pylint: disable=too-many-branches,too-many-statements # pylint: disable=too-many-branches,too-many-statements
import ctypes
import logging import logging
import os import os
import platform import platform
import socket
import sys import sys
import time import time
from distutils.version import StrictVersion from distutils.version import StrictVersion
from struct import pack
try: try:
import defaults import defaults
@ -304,6 +307,68 @@ def adjustHalfOpenConnectionsLimit():
state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64 state.maximumNumberOfHalfOpenConnections = 9 if is_limited else 64
def fixSocket():
"""Add missing socket options and methods mainly on Windows"""
if sys.platform.startswith('linux'):
socket.SO_BINDTODEVICE = 25
if not sys.platform.startswith('win'):
return
# Python 2 on Windows doesn't define a wrapper for
# socket.inet_ntop but we can make one ourselves using ctypes
if not hasattr(socket, 'inet_ntop'):
addressToString = ctypes.windll.ws2_32.WSAAddressToStringA
def inet_ntop(family, host):
"""Converting an IP address in packed
binary format to string format"""
if family == socket.AF_INET:
if len(host) != 4:
raise ValueError("invalid IPv4 host")
host = pack("hH4s8s", socket.AF_INET, 0, host, "\0" * 8)
elif family == socket.AF_INET6:
if len(host) != 16:
raise ValueError("invalid IPv6 host")
host = pack("hHL16sL", socket.AF_INET6, 0, 0, host, 0)
else:
raise ValueError("invalid address family")
buf = "\0" * 64
lengthBuf = pack("I", len(buf))
addressToString(host, len(host), None, buf, lengthBuf)
return buf[0:buf.index("\0")]
socket.inet_ntop = inet_ntop
# Same for inet_pton
if not hasattr(socket, 'inet_pton'):
stringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
def inet_pton(family, host):
"""Converting an IP address in string format
to a packed binary format"""
buf = "\0" * 28
lengthBuf = pack("I", len(buf))
if stringToAddress(str(host),
int(family),
None,
buf,
lengthBuf) != 0:
raise socket.error("illegal IP address passed to inet_pton")
if family == socket.AF_INET:
return buf[4:8]
elif family == socket.AF_INET6:
return buf[8:24]
else:
raise ValueError("invalid address family")
socket.inet_pton = inet_pton
# These sockopts are needed on for IPv6 support
if not hasattr(socket, 'IPPROTO_IPV6'):
socket.IPPROTO_IPV6 = 41
if not hasattr(socket, 'IPV6_V6ONLY'):
socket.IPV6_V6ONLY = 27
def start_proxyconfig(): def start_proxyconfig():
"""Check socksproxytype and start any proxy configuration plugin""" """Check socksproxytype and start any proxy configuration plugin"""
if not get_plugin: if not get_plugin:

View File

@ -6,11 +6,17 @@ import sys
import unittest import unittest
from pybitmessage import protocol, state from pybitmessage import protocol, state
from pybitmessage.helper_startup import fixSocket
class TestProtocol(unittest.TestCase): class TestProtocol(unittest.TestCase):
"""Main protocol test case""" """Main protocol test case"""
@classmethod
def setUpClass(cls):
"""Execute fixSocket() before start. Only for Windows?"""
fixSocket()
def test_checkIPv4Address(self): def test_checkIPv4Address(self):
"""Check the results of protocol.checkIPv4Address()""" """Check the results of protocol.checkIPv4Address()"""
token = 'HELLO' token = 'HELLO'