Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,24 @@ Redistribution and use in source and binary forms, with or without modification,
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

===== based on asyncore_pollchoose.py asyncore_pollchoose python implementation. by Sam Rushing <rushing@nightmare.com>

Copyright 1996 by Sam Rushing. All Rights Reserved

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of Sam
Rushing not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3 changes: 3 additions & 0 deletions src/network/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"""
Network subsystem packages
Comment thread
lakshyacis marked this conversation as resolved.
"""
from addrthread import AddrThread
from announcethread import AnnounceThread
from connectionpool import BMConnectionPool
Expand Down
1 change: 1 addition & 0 deletions src/network/addrthread.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


class AddrThread(StoppableThread):
"""(Node) address broadcasting thread"""
name = "AddrBroadcaster"

def run(self):
Expand Down
35 changes: 20 additions & 15 deletions src/network/advanceddispatcher.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""
src/network/advanceddispatcher.py
=================================
Improved version of asyncore dispatcher
"""
# pylint: disable=attribute-defined-outside-init

import socket
import threading
import time
Expand All @@ -14,7 +12,8 @@


class ProcessingError(Exception):
"""General class for protocol parser exception, use as a base for others."""
"""General class for protocol parser exception,
use as a base for others."""
pass


Expand All @@ -24,7 +23,8 @@ class UnknownStateError(ProcessingError):


class AdvancedDispatcher(asyncore.dispatcher):
"""Improved version of asyncore dispatcher, with buffers and protocol state."""
"""Improved version of asyncore dispatcher,
with buffers and protocol state."""
# pylint: disable=too-many-instance-attributes
_buf_len = 131072 # 128kB

Expand Down Expand Up @@ -72,7 +72,8 @@ def slice_read_buf(self, length=0):
del self.read_buf[0:length]

def process(self):
"""Process (parse) data that's in the buffer, as long as there is enough data and the connection is open."""
"""Process (parse) data that's in the buffer,
as long as there is enough data and the connection is open."""
while self.connected and not state.shutdown:
try:
with nonBlocking(self.processingLock):
Expand Down Expand Up @@ -104,8 +105,9 @@ def writable(self):
if asyncore.maxUploadRate > 0:
self.uploadChunk = int(asyncore.uploadBucket)
self.uploadChunk = min(self.uploadChunk, len(self.write_buf))
return asyncore.dispatcher.writable(self) and \
(self.connecting or (self.connected and self.uploadChunk > 0))
return asyncore.dispatcher.writable(self) and (
self.connecting or (
self.connected and self.uploadChunk > 0))

def readable(self):
"""Is the read buffer ready to accept data from the network?"""
Expand All @@ -114,13 +116,15 @@ def readable(self):
self.downloadChunk = int(asyncore.downloadBucket)
try:
if self.expectBytes > 0 and not self.fullyEstablished:
self.downloadChunk = min(self.downloadChunk, self.expectBytes - len(self.read_buf))
self.downloadChunk = min(
self.downloadChunk, self.expectBytes - len(self.read_buf))
if self.downloadChunk < 0:
self.downloadChunk = 0
except AttributeError:
pass
return asyncore.dispatcher.readable(self) and \
(self.connecting or self.accepting or (self.connected and self.downloadChunk > 0))
return asyncore.dispatcher.readable(self) and (
self.connecting or self.accepting or (
self.connected and self.downloadChunk > 0))

def handle_read(self):
"""Append incoming data to the read buffer."""
Expand All @@ -144,20 +148,21 @@ def handle_connect_event(self):
try:
asyncore.dispatcher.handle_connect_event(self)
except socket.error as e:
if e.args[0] not in asyncore._DISCONNECTED: # pylint: disable=protected-access
# pylint: disable=protected-access
if e.args[0] not in asyncore._DISCONNECTED:
raise

def handle_connect(self):
"""Method for handling connection established implementations."""
self.lastTx = time.time()

def state_close(self):
def state_close(self): # pylint: disable=no-self-use
"""Signal to the processing loop to end."""
# pylint: disable=no-self-use
return False

def handle_close(self):
"""Callback for connection being closed, but can also be called directly when you want connection to close."""
"""Callback for connection being closed,
but can also be called directly when you want connection to close."""
with self.readLock:
self.read_buf = bytearray()
with self.writeLock:
Expand Down
7 changes: 3 additions & 4 deletions src/network/announcethread.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""
src/network/announcethread.py
=================================
Announce myself (node address)
"""

import time

import state
Expand Down Expand Up @@ -40,6 +38,7 @@ def announceSelf():
stream,
Peer(
'127.0.0.1',
BMConfigParser().safeGetInt('bitmessagesettings', 'port')),
BMConfigParser().safeGetInt(
'bitmessagesettings', 'port')),
time.time())
connection.append_write_buf(assemble_addr([addr]))
17 changes: 8 additions & 9 deletions src/network/assemble.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
Create bitmessage protocol command packets
"""

import struct

import addresses
Expand All @@ -13,20 +12,20 @@
def assemble_addr(peerList):
"""Create address command"""
if isinstance(peerList, Peer):
peerList = (peerList)
peerList = [peerList]
if not peerList:
return b''
retval = b''
for i in range(0, len(peerList), MAX_ADDR_COUNT):
payload = addresses.encodeVarint(
len(peerList[i:i + MAX_ADDR_COUNT]))
payload = addresses.encodeVarint(len(peerList[i:i + MAX_ADDR_COUNT]))
for stream, peer, timestamp in peerList[i:i + MAX_ADDR_COUNT]:
payload += struct.pack(
'>Q', timestamp) # 64-bit time
# 64-bit time
payload += struct.pack('>Q', timestamp)
payload += struct.pack('>I', stream)
payload += struct.pack(
'>q', 1) # service bit flags offered by this node
# service bit flags offered by this node
payload += struct.pack('>q', 1)
payload += encodeHost(peer.host)
payload += struct.pack('>H', peer.port) # remote port
# remote port
payload += struct.pack('>H', peer.port)
retval += CreatePacket('addr', payload)
return retval
Loading