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
depends.check_dependencies()
import ctypes
import getopt
import multiprocessing
# Used to capture a Ctrl-C keypress so that Bitmessage can shutdown gracefully.
import signal
import socket
import threading
import time
import traceback
from struct import pack
import defaults
import shared
@ -39,7 +36,7 @@ import state
from bmconfigparser import BMConfigParser
from debug import logger # this should go before any threads
from helper_startup import (
adjustHalfOpenConnectionsLimit, start_proxyconfig)
adjustHalfOpenConnectionsLimit, fixSocket, start_proxyconfig)
from inventory import Inventory
# Network objects and threads
from network import (
@ -54,67 +51,6 @@ from threads import (
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):
"""Single handler for any signal sent to pybitmessage"""
process = multiprocessing.current_process()
@ -151,7 +87,7 @@ class Main(object):
def start(self):
"""Start main application"""
# pylint: disable=too-many-statements,too-many-branches,too-many-locals
_fixSocket()
fixSocket()
adjustHalfOpenConnectionsLimit()
config = BMConfigParser()

View File

@ -3,12 +3,15 @@ Startup operations.
"""
# pylint: disable=too-many-branches,too-many-statements
import ctypes
import logging
import os
import platform
import socket
import sys
import time
from distutils.version import StrictVersion
from struct import pack
try:
import defaults
@ -304,6 +307,68 @@ def adjustHalfOpenConnectionsLimit():
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():
"""Check socksproxytype and start any proxy configuration plugin"""
if not get_plugin:

View File

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