2017-06-09 20:41:33 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import logging
|
|
|
|
import socket
|
|
|
|
import threading
|
|
|
|
|
2021-03-09 15:40:59 +01:00
|
|
|
from .util import receive_line
|
2017-06-09 20:41:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
class I2PListener(threading.Thread):
|
2021-03-09 15:40:59 +01:00
|
|
|
def __init__(self, state, nick, host='127.0.0.1', port=7656):
|
2017-06-09 20:41:33 +02:00
|
|
|
super().__init__(name='I2P Listener')
|
|
|
|
|
2021-03-09 15:40:59 +01:00
|
|
|
self.state = state
|
2017-06-09 20:41:33 +02:00
|
|
|
self.host = host
|
|
|
|
self.port = port
|
|
|
|
self.nick = nick
|
|
|
|
|
|
|
|
self.s = None
|
|
|
|
|
|
|
|
self.version_reply = []
|
|
|
|
|
2017-07-30 09:26:16 +02:00
|
|
|
self.new_socket()
|
2017-06-09 20:41:33 +02:00
|
|
|
|
|
|
|
def _receive_line(self):
|
|
|
|
line = receive_line(self.s)
|
2021-03-08 16:06:07 +01:00
|
|
|
# logging.debug('I2PListener <- %s', line)
|
2017-06-09 20:41:33 +02:00
|
|
|
return line
|
|
|
|
|
|
|
|
def _send(self, command):
|
2021-03-08 16:06:07 +01:00
|
|
|
# logging.debug('I2PListener -> %s', command)
|
2017-06-09 20:41:33 +02:00
|
|
|
self.s.sendall(command)
|
|
|
|
|
2017-07-30 09:26:16 +02:00
|
|
|
def new_socket(self):
|
2017-06-09 20:41:33 +02:00
|
|
|
self.s = socket.create_connection((self.host, self.port))
|
|
|
|
self._send(b'HELLO VERSION MIN=3.0 MAX=3.3\n')
|
|
|
|
self.version_reply = self._receive_line().split()
|
|
|
|
assert b'RESULT=OK' in self.version_reply
|
|
|
|
|
|
|
|
self._send(b'STREAM ACCEPT ID=' + self.nick + b'\n')
|
|
|
|
reply = self._receive_line().split(b' ')
|
|
|
|
assert b'RESULT=OK' in reply
|
|
|
|
|
|
|
|
self.s.settimeout(1)
|
|
|
|
|
|
|
|
def run(self):
|
2021-03-09 15:40:59 +01:00
|
|
|
while not self.state.shutting_down:
|
2017-06-09 20:41:33 +02:00
|
|
|
try:
|
|
|
|
destination = self._receive_line().split()[0]
|
2021-03-08 16:06:07 +01:00
|
|
|
logging.info(
|
|
|
|
'Incoming I2P connection from: %s', destination.decode())
|
2017-07-30 09:26:16 +02:00
|
|
|
|
|
|
|
hosts = set()
|
2021-03-09 15:40:59 +01:00
|
|
|
for c in self.state.connections.copy():
|
2017-07-30 09:26:16 +02:00
|
|
|
hosts.add(c.host)
|
2021-03-09 15:40:59 +01:00
|
|
|
for d in self.state.i2p_dialers.copy():
|
2017-07-30 09:26:16 +02:00
|
|
|
hosts.add(d.destination)
|
|
|
|
if destination in hosts:
|
|
|
|
logging.debug('Rejecting duplicate I2P connection.')
|
|
|
|
self.s.close()
|
|
|
|
else:
|
2021-03-09 15:40:59 +01:00
|
|
|
c = self.state.connection(
|
|
|
|
destination, 'i2p', self.s, 'i2p', True, destination)
|
2017-07-30 09:26:16 +02:00
|
|
|
c.start()
|
2021-03-09 15:40:59 +01:00
|
|
|
self.state.connections.add(c)
|
2017-07-30 09:26:16 +02:00
|
|
|
self.new_socket()
|
2017-06-09 20:41:33 +02:00
|
|
|
except socket.timeout:
|
|
|
|
pass
|
|
|
|
logging.debug('Shutting down I2P Listener')
|