Asyncore updates

- mainly work on proxy support, but it's still not fully working
- minor bugfixes
This commit is contained in:
Peter Šurda 2017-06-10 10:13:49 +02:00
parent 7deb7c3d4f
commit cba749088a
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
9 changed files with 53 additions and 21 deletions

View File

@ -57,7 +57,7 @@ import warnings
import os import os
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \ from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \
ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \
ECONNREFUSED, EHOSTUNREACH, ENETUNREACH, ENOTSOCK, \ ECONNREFUSED, EHOSTUNREACH, ENETUNREACH, ENOTSOCK, EINTR, \
errorcode errorcode
try: try:
from errno import WSAEWOULDBLOCK from errno import WSAEWOULDBLOCK

View File

@ -282,11 +282,11 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
except (BMObjectExpiredError, BMObjectUnwantedStreamError): except (BMObjectExpiredError, BMObjectUnwantedStreamError):
for connection in network.connectionpool.BMConnectionPool().inboundConnections.values() + network.connectionpool.BMConnectionPool().outboundConnections.values(): for connection in network.connectionpool.BMConnectionPool().inboundConnections.values() + network.connectionpool.BMConnectionPool().outboundConnections.values():
try: try:
del connection.objectsNewtoThem[hashId] del connection.objectsNewtoThem[self.object.inventoryHash]
except KeyError: except KeyError:
pass pass
try: try:
del connection.objectsNewToMe[hashId] del connection.objectsNewToMe[self.object.inventoryHash]
except KeyError: except KeyError:
pass pass
if not BMConfigParser().get("inventory", "acceptmismatch"): if not BMConfigParser().get("inventory", "acceptmismatch"):
@ -459,7 +459,10 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
def handle_close(self, reason=None): def handle_close(self, reason=None):
self.set_state("close") self.set_state("close")
if reason is None: if reason is None:
try:
logger.debug("%s:%i: closing", self.destination.host, self.destination.port) logger.debug("%s:%i: closing", self.destination.host, self.destination.port)
except AttributeError:
logger.debug("Disconnected socket closing")
else: else:
logger.debug("%s:%i: closing, %s", self.destination.host, self.destination.port, reason) logger.debug("%s:%i: closing, %s", self.destination.host, self.destination.port, reason)
AdvancedDispatcher.handle_close(self) AdvancedDispatcher.handle_close(self)

View File

@ -7,6 +7,7 @@ import re
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from debug import logger from debug import logger
import helper_bootstrap import helper_bootstrap
from network.proxy import Proxy
import network.bmproto import network.bmproto
import network.tcp import network.tcp
import network.udp import network.udp
@ -129,6 +130,8 @@ class BMConnectionPool(object):
if not self.bootstrapped: if not self.bootstrapped:
helper_bootstrap.dns() helper_bootstrap.dns()
self.bootstrapped = True self.bootstrapped = True
Proxy.proxy = (BMConfigParser().safeGet("bitmessagesettings", "sockshostname"),
BMConfigParser().safeGetInt("bitmessagesettings", "socksport"))
established = sum(1 for c in self.outboundConnections.values() if (c.connected and c.fullyEstablished)) established = sum(1 for c in self.outboundConnections.values() if (c.connected and c.fullyEstablished))
pending = len(self.outboundConnections) - established pending = len(self.outboundConnections) - established
if established < BMConfigParser().safeGetInt("bitmessagesettings", "maxoutboundconnections"): if established < BMConfigParser().safeGetInt("bitmessagesettings", "maxoutboundconnections"):

View File

@ -54,6 +54,7 @@ class ObjectTracker(object):
def clean(self): def clean(self):
if self.lastCleaned < time.time() - ObjectTracker.invCleanPeriod: if self.lastCleaned < time.time() - ObjectTracker.invCleanPeriod:
if haveBloom: if haveBloom:
# FIXME
if PendingDownloadQueue().size() == 0: if PendingDownloadQueue().size() == 0:
self.initInvBloom() self.initInvBloom()
self.initAddrBloom() self.initAddrBloom()

View File

@ -1,7 +1,10 @@
import socket import socket
import state
from advanceddispatcher import AdvancedDispatcher from advanceddispatcher import AdvancedDispatcher
import asyncore_pollchoose as asyncore import asyncore_pollchoose as asyncore
import network.connectionpool
class ProxyError(Exception): pass class ProxyError(Exception): pass
class GeneralProxyError(ProxyError): pass class GeneralProxyError(ProxyError): pass
@ -32,10 +35,25 @@ class Proxy(AdvancedDispatcher):
self.__class__._auth = authTuple self.__class__._auth = authTuple
def __init__(self, address): def __init__(self, address):
if type(address) != tuple or (len(address) < 2) or (type(str(address[0])) != type('')) or (type(address[1]) != int): if not isinstance(address, state.Peer):
raise ValueError raise ValueError
AdvancedDispatcher.__init__(self) AdvancedDispatcher.__init__(self)
self.destination = address self.destination = address
self.isOutbound = True
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect(self.proxy) self.connect(self.proxy)
print "connecting in background to %s:%i" % (self.proxy[0], self.proxy[1]) print "connecting in background to %s:%i" % (self.proxy[0], self.proxy[1])
def handle_connect(self):
try:
AdvancedDispatcher.handle_connect(self)
except socket.error as e:
if e.errno in asyncore._DISCONNECTED:
logger.debug("%s:%i: Connection failed: %s" % (self.destination.host, self.destination.port, str(e)))
return
def state_proxy_handshake_done(self):
self.writeQueue.put(protocol.assembleVersionMessage(self.destination.host, self.destination.port, network.connectionpool.BMConnectionPool().streams, False))
self.connectedAt = time.time()
return False

View File

@ -43,7 +43,7 @@ class Socks4a(Proxy):
self.__proxypeername = (socket.inet_ntoa(self.ipaddr), self.destination[1]) self.__proxypeername = (socket.inet_ntoa(self.ipaddr), self.destination[1])
else: else:
self.__proxypeername = (self.destination[0], self.destport) self.__proxypeername = (self.destination[0], self.destport)
self.set_state("socks_handshake_done", 8) self.set_state("proxy_handshake_done", 8)
def proxy_sock_name(self): def proxy_sock_name(self):
return socket.inet_ntoa(self.__proxysockname[0]) return socket.inet_ntoa(self.__proxysockname[0])

View File

@ -4,6 +4,7 @@ import struct
from advanceddispatcher import AdvancedDispatcher from advanceddispatcher import AdvancedDispatcher
import asyncore_pollchoose as asyncore import asyncore_pollchoose as asyncore
from proxy import Proxy, ProxyError, GeneralProxyError from proxy import Proxy, ProxyError, GeneralProxyError
import network.connectionpool
class Socks5AuthError(ProxyError): pass class Socks5AuthError(ProxyError): pass
class Socks5Error(ProxyError): pass class Socks5Error(ProxyError): pass
@ -103,7 +104,7 @@ class Socks5(Proxy):
def state_proxy_addr_2_2(self): def state_proxy_addr_2_2(self):
if not self.read_buf_sufficient(self.address_length): if not self.read_buf_sufficient(self.address_length):
return False return False
self.boundaddr = read_buf self.boundaddr = self.read_buf
self.set_state("proxy_port", self.address_length) self.set_state("proxy_port", self.address_length)
def state_proxy_port(self): def state_proxy_port(self):
@ -115,14 +116,11 @@ class Socks5(Proxy):
self.__proxypeername = (socket.inet_ntoa(self.ipaddr), self.destination[1]) self.__proxypeername = (socket.inet_ntoa(self.ipaddr), self.destination[1])
else: else:
self.__proxypeername = (self.destination[0], self.destport) self.__proxypeername = (self.destination[0], self.destport)
self.set_state("socks_handshake_done", 2) self.set_state("proxy_handshake_done", 2)
def proxy_sock_name(self): def proxy_sock_name(self):
return socket.inet_ntoa(self.__proxysockname[0]) return socket.inet_ntoa(self.__proxysockname[0])
def state_socks_handshake_done(self):
return False
class Socks5Connection(Socks5): class Socks5Connection(Socks5):
def __init__(self, address): def __init__(self, address):

View File

@ -49,6 +49,10 @@ class TCPConnection(BMProto, TLSDispatcher):
TLSDispatcher.__init__(self, sock, server_side=True) TLSDispatcher.__init__(self, sock, server_side=True)
self.connectedAt = time.time() self.connectedAt = time.time()
logger.debug("Received connection from %s:%i", self.destination.host, self.destination.port) logger.debug("Received connection from %s:%i", self.destination.host, self.destination.port)
elif address is not None and sock is not None:
TLSDispatcher.__init__(self, sock, server_side=False)
self.isOutbound = True
logger.debug("Outbound proxy connection to %s:%i", self.destination.host, self.destination.port)
else: else:
self.destination = address self.destination = address
self.isOutbound = True self.isOutbound = True
@ -159,33 +163,37 @@ class TCPConnection(BMProto, TLSDispatcher):
self.connectedAt = time.time() self.connectedAt = time.time()
def handle_read(self): def handle_read(self):
try: # try:
TLSDispatcher.handle_read(self) TLSDispatcher.handle_read(self)
except socket.error as e: # except socket.error as e:
logger.debug("%s:%i: Handle read fail: %s" % (self.destination.host, self.destination.port, str(e))) # logger.debug("%s:%i: Handle read fail: %s" % (self.destination.host, self.destination.port, str(e)))
def handle_write(self): def handle_write(self):
try: # try:
TLSDispatcher.handle_write(self) TLSDispatcher.handle_write(self)
except socket.error as e: # except socket.error as e:
logger.debug("%s:%i: Handle write fail: %s" % (self.destination.host, self.destination.port, str(e))) # logger.debug("%s:%i: Handle write fail: %s" % (self.destination.host, self.destination.port, str(e)))
class Socks5BMConnection(Socks5Connection, TCPConnection): class Socks5BMConnection(Socks5Connection, TCPConnection):
def __init__(self, address): def __init__(self, address):
Socks5Connection.__init__(self, address=address) Socks5Connection.__init__(self, address=address)
TCPConnection.__init__(self, address=address, sock=self.socket)
self.set_state("init")
def state_socks_handshake_done(self): def state_socks_handshake_done(self):
TCPConnection.state_init(self) self.set_state("bm_header", expectBytes=protocol.Header.size)
return False return False
class Socks4aBMConnection(Socks4aConnection, TCPConnection): class Socks4aBMConnection(Socks4aConnection, TCPConnection):
def __init__(self, address): def __init__(self, address):
Socks4aConnection.__init__(self, address=address) Socks4aConnection.__init__(self, address=address)
TCPConnection.__init__(self, address=address, sock=self.socket)
self.set_state("init")
def state_socks_handshake_done(self): def state_socks_handshake_done(self):
TCPConnection.state_init(self) self.set_state("bm_header", expectBytes=protocol.Header.size)
return False return False

View File

@ -3,6 +3,7 @@ from binascii import hexlify
import hashlib import hashlib
import math import math
import time import time
import Queue
import socket import socket
import struct import struct
import random import random