revert network/tcp.py and add changes to multiaddr_to_socket_fix

This commit is contained in:
Jonathan de Jong 2019-12-19 21:09:11 +01:00
parent 0827d0d9ef
commit df8be6eb09

View File

@ -1,11 +1,9 @@
import asyncio import asyncio
import socket from socket import socket
import sys import sys
from typing import List, Optional from typing import List
from multiaddr import Multiaddr from multiaddr import Multiaddr
from multiaddr.protocols import P_IP4, P_IP6, P_TCP, P_UDP
from multiaddr.protocols import protocol_with_code as p_code
from libp2p.network.connection.raw_connection import RawConnection from libp2p.network.connection.raw_connection import RawConnection
from libp2p.network.connection.raw_connection_interface import IRawConnection from libp2p.network.connection.raw_connection_interface import IRawConnection
@ -31,14 +29,10 @@ class TCPListener(IListener):
:param maddr: maddr of peer :param maddr: maddr of peer
:return: return True if successful :return: return True if successful
""" """
listen_addr = _ip4_or_6_from_multiaddr(maddr)
if listen_addr is None:
raise NotImplementedError(
"Can only start TCP Listener with a IPv4 or IPv6 address"
)
self.server = await asyncio.start_server( self.server = await asyncio.start_server(
self.handler, listen_addr, maddr.value_for_protocol("tcp") self.handler,
maddr.value_for_protocol("ip4"),
maddr.value_for_protocol("tcp"),
) )
socket = self.server.sockets[0] socket = self.server.sockets[0]
self.multiaddrs.append(_multiaddr_from_socket(socket)) self.multiaddrs.append(_multiaddr_from_socket(socket))
@ -76,10 +70,7 @@ class TCP(ITransport):
:return: `RawConnection` if successful :return: `RawConnection` if successful
:raise OpenConnectionError: raised when failed to open connection :raise OpenConnectionError: raised when failed to open connection
""" """
self.host = _ip4_or_6_from_multiaddr(maddr) self.host = maddr.value_for_protocol("ip4")
if self.host is None:
raise ValueError("Cannot find ipv4 or ipv6 host in multiaddress")
self.port = int(maddr.value_for_protocol("tcp")) self.port = int(maddr.value_for_protocol("tcp"))
try: try:
@ -100,52 +91,6 @@ class TCP(ITransport):
return TCPListener(handler_function) return TCPListener(handler_function)
def _ip4_or_6_from_multiaddr(maddr: Multiaddr) -> Optional[str]: def _multiaddr_from_socket(socket: socket) -> Multiaddr:
if P_IP4 in maddr.protocols(): addr, port = socket.getsockname()[:2]
return maddr.value_for_protocol(P_IP4) return Multiaddr(f"/ip4/{addr}/tcp/{port}")
elif P_IP6 in maddr.protocols():
return maddr.value_for_protocol(P_IP6)
else:
return None
def _multiaddr_from_socket(sock: socket.socket) -> Multiaddr:
# Reference: http://man7.org/linux/man-pages/man2/socket.2.html#DESCRIPTION
# todo: move this to more generic libp2p.transport helper function
# Reference: https://stackoverflow.com/questions/5815675/what-is-sock-dgram-and-sock-stream
# Selects first protocol in sequence if bitwise AND matches, else None
t_proto = next(
(
v
for k, v in {
socket.SOCK_STREAM: p_code(P_TCP).name,
socket.SOCK_DGRAM: p_code(P_UDP).name,
}.items()
if k & sock.type != 0
),
None,
)
if t_proto is None:
raise NotImplementedError(
f"Cannot convert socket to multiaddr, socket type is of {sock.type}"
)
# Reference: https://docs.python.org/3/library/socket.html#socket-families
if sock.family == socket.AF_INET:
# ipv4: (host, port)
addr, port = sock.getsockname()
ip = p_code(P_IP4).name
elif sock.family == socket.AF_INET6:
# ipv6: (host, port, flowinfo, scopeid)
addr, port = sock.getsockname()[:2]
ip = p_code(P_IP6).name
else:
raise NotImplementedError(
f"Cannot convert socket to multiaddr, socket family is of {sock.family}"
)
return Multiaddr(f"/{ip}/{addr}/{t_proto}/{port}")