Git Product home page Git Product logo

minode's Introduction

MiNode

Python 3 implementation of the Bitmessage protocol. Designed only to route objects inside the network.

Requirements

  • python3 (or pypy3)
  • openssl

Running

git clone https://github.com/TheKysek/MiNode.git
cd MiNode
chmod +x start.sh
./start.sh

It is worth noting that the start.sh file MiNode no longer tries to do a git pull in order to update to the latest version. Is is now done by the update.sh file.

Command line

usage: main.py [-h] [-p PORT] [--host HOST] [--debug] [--data-dir DATA_DIR]
               [--no-incoming] [--no-outgoing] [--no-ip]
               [--trusted-peer TRUSTED_PEER]
               [--connection-limit CONNECTION_LIMIT] [--i2p]
               [--i2p-tunnel-length I2P_TUNNEL_LENGTH]
               [--i2p-sam-host I2P_SAM_HOST] [--i2p-sam-port I2P_SAM_PORT]

optional arguments:
  -h, --help            show this help message and exit
  -p PORT, --port PORT  Port to listen on
  --host HOST           Listening host
  --debug               Enable debug logging
  --data-dir DATA_DIR   Path to data directory
  --no-incoming         Do not listen for incoming connections
  --no-outgoing         Do not send outgoing connections
  --no-ip               Do not use IP network
  --trusted-peer TRUSTED_PEER
                        Specify a trusted peer we should connect to
  --connection-limit CONNECTION_LIMIT
                        Maximum number of connections
  --i2p                 Enable I2P support (uses SAMv3)
  --i2p-tunnel-length I2P_TUNNEL_LENGTH
                        Length of I2P tunnels
  --i2p-sam-host I2P_SAM_HOST
                        Host of I2P SAMv3 bridge
  --i2p-sam-port I2P_SAM_PORT
                        Port of I2P SAMv3 bridge

I2P support

MiNode has support for connections over I2P network. To use it it needs an I2P router with SAMv3 activated (both Java I2P and i2pd are supported). Keep in mind that I2P connections are slow and full synchronization may take a while.

Examples

Connect to both IP and I2P networks (SAM bridge on default host and port 127.0.0.1:7656) and set tunnel length to 3 (default is 2).

$ ./start.sh --i2p --i2p-tunnel-length 3

Connect only to I2P network and listen for IP connections only from local machine.

$ ./start.sh --i2p --no-ip --host 127.0.0.1

or

$ ./i2p_bridge.sh

If you add trustedpeer = 127.0.0.1:8444 to keys.dat file in PyBitmessage it will allow you to use it anonymously over I2P with MiNode acting as a bridge.

Contact

  • TheKysek: BM-2cVUMXVnQXmTJDmb7q1HUyEqkT92qjwGvJ

Links

minode's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

minode's Issues

Does MiNode always advertise the correct port?

TL;DR: Does MiNode incorrectly advertise the portnumber(s) of one or more of its outgoing connections as its listening address?

I have a TCP logger running on the same box as MiNode and when someone attempts a SYN on the net device a line like

Aug  4 16:15:43 example tcplog[123]: port 8444 (bitmessage) request from node.example.com[1.2.3.4]

will be written to syslog.

MiNode and PyBitmessage in general both listen on port 8444 so that when net connections are listed with netstat -anp incoming connection will have port 8444 in the left hand column and a port > 1024 (but not 8444) in the right hand column, whereas outgoing connections will have port 8444 in the right hand column and a port > 1024 (but not 8444) in the left hand column.

Now, what puzzles me about the box where I'm running MiNode is that I see a lot of “… port NNNNN (unknown) request from …” lines from tcplog, where NNNNN > 1024 (but not 8444). And when I look up NNNNN with netstat(8) the port often happens to be one of MiNode's outgoing connections (sometimes the port is not listed in netstat(8), but it never belongs to another listening program than MiNode). I never see this pattern on a box that runs PyBitmessage.

AFAIK, all connections in MiNode (and PyBitmessage) are unidirectional, so this begs the question: Does MiNode incorrectly advertise the portnumber(s) of one or more of its outgoing connections as its listening address?

Uncaught exception: socket.timeout: timed out

Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 78, in run
    self._process_queue()
  File "…/MiNode/src/connection.py", line 154, in _process_queue
    self._send_message(m)
  File "…/MiNode/src/connection.py", line 131, in _send_message
    self.s.sendall(m.to_bytes())
socket.timeout: timed out

Please note that this is different from #3

Uncaught exception: ssl.SSLError: ssl handshake failure

Spotted in the wild:

Exception in thread Connection to ${IP_ADDRESS_AND_PORT}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 78, in run
    self._process_queue()
  File "…/MiNode/src/connection.py", line 154, in _process_queue
    self._send_message(m)
  File "…/MiNode/src/connection.py", line 131, in _send_message
    self.s.sendall(m.to_bytes())
  File "/usr/lib/python3.5/ssl.py", line 891, in sendall
    v = self.send(data[count:])
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
ssl.SSLError: [SSL: SSL_HANDSHAKE_FAILURE] ssl handshake failure (_ssl.c:1844)

Uncaught exception: ConnectionResetError: [Errno 104] Connection reset by peer

Exception in thread Connection to ${IP_ADDRESS_AND_PORT}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 78, in run
    self._process_queue()
  File "…/MiNode/src/connection.py", line 154, in _process_queue
    self._send_message(m)
  File "…/MiNode/src/connection.py", line 131, in _send_message
    self.s.sendall(m.to_bytes())
  File "/usr/lib/python3.5/ssl.py", line 891, in sendall
    v = self.send(data[count:])
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
ConnectionResetError: [Errno 104] Connection reset by peer

Uncaught exceptions: ssl.SSLError and ConnectionResetError

The three exceptions shown here were all seen multiple times with the current git version during the last 24 hours:

Exception in thread Connection to ${UNDISCLOSED_IP_ADDRESS}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/minode/src/connection.py", line 92, in run
    self._send_data()
  File "…/minode/src/connection.py", line 128, in _send_data
    amount = self.s.send(self.buffer_send)
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
ssl.SSLError: [SSL: UNEXPECTED_RECORD] unexpected record (_ssl.c:1844)
Exception in thread Connection to ${UNDISCLOSED_IP_ADDRESS}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/minode/src/connection.py", line 92, in run
    self._send_data()
  File "…/minode/src/connection.py", line 128, in _send_data
    amount = self.s.send(self.buffer_send)
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
ConnectionResetError: [Errno 104] Connection reset by peer
Exception in thread Connection to ${UNDISCLOSED_IP_ADDRESS}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/minode/src/connection.py", line 92, in run
    self._send_data()
  File "…/minode/src/connection.py", line 128, in _send_data
    amount = self.s.send(self.buffer_send)
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
ssl.SSLError: [SSL: SSL_HANDSHAKE_FAILURE] ssl handshake failure (_ssl.c:1844)

Uncaught exception: AssertionError

Exception in thread Connection to ${IP_ADDRESS_AND_PORT}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 76, in run
    self._process_buffer()
  File "…/MiNode/src/connection.py", line 173, in _process_buffer
    self._process_message(m)
  File "…/MiNode/src/connection.py", line 200, in _process_message
    inv = message.Inv.from_message(m)
  File "…/MiNode/src/message.py", line 161, in from_message
    assert vector_count == len(vectors)
AssertionError

Uncaught exception: socket.timeout: The write operation timed out

Exceptions like this are seen regularly:

Exception in thread Connection to ${IP_ADDRESS_AND_PORT}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 78, in run
    self._process_queue()
  File "…/MiNode/src/connection.py", line 154, in _process_queue
    self._send_message(m)
  File "…/MiNode/src/connection.py", line 131, in _send_message
    self.s.sendall(m.to_bytes())
  File "/usr/lib/python3.5/ssl.py", line 891, in sendall
    v = self.send(data[count:])
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
socket.timeout: The write operation timed out

Please note that this is different from #6

Doesn't seem to listen on IPv6

While MiNode connects to IPv6 nodes without any problems, it doesn't seem to listen on IPv6. Using netstat(8) I do see

tcp        0      0 0.0.0.0:8444            0.0.0.0:*               LISTEN      19564/python

but I would also expect a line like this:

tcp6       0      0 :::8444                 :::*                    LISTEN      19564/python

Uncaught exception: BrokenPipeError: [Errno 32] Broken pipe

Exception in thread Connection to ${IP_ADDRESS_AND_PORT}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 78, in run
    self._process_queue()
  File "…/MiNode/src/connection.py", line 154, in _process_queue
    self._send_message(m)
  File "…/MiNode/src/connection.py", line 131, in _send_message
    self.s.sendall(m.to_bytes())
  File "/usr/lib/python3.5/ssl.py", line 891, in sendall
    v = self.send(data[count:])
  File "/usr/lib/python3.5/ssl.py", line 861, in send
    return self._sslobj.write(data)
  File "/usr/lib/python3.5/ssl.py", line 586, in write
    return self._sslobj.write(data)
BrokenPipeError: [Errno 32] Broken pipe

Use SQLite instead of pickle for object handling

Krzysztof,
Thanks for sharing your source code! It's clean and easy to read.

Not sure whether you are still working on it, but I think it should be better to use some database for the objects, so some future API can use it as well. Hence I have created this issue.

Uncaught exception: OSError: magic_bytes do not match

Every now and then the following exception is seen:

Exception in thread Connection to ${IP_ADDRESS_AND_PORT}:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "…/MiNode/src/connection.py", line 76, in run
    self._process_buffer()
  File "…/MiNode/src/connection.py", line 164, in _process_buffer
    h = message.Header.from_bytes(self.buffer[:shared.header_length])
  File "…/MiNode/src/message.py", line 34, in from_bytes
    raise IOError('magic_bytes do not match')
OSError: magic_bytes do not match

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.