This commit is contained in:
emdee 2022-10-07 04:47:34 +00:00
parent 8018e5a89e
commit 4d51ddbeb3
5 changed files with 77 additions and 33 deletions

View File

@ -17,7 +17,8 @@ that every call in ```tox.py``` has the right signature, but it runs
It has been tested with UDP and TCP proxy (Tor). It has ***not*** been
tested on Windows, and there may be some minor breakage, which should be
easy to fix. There is a good coverage integration testsuite in ```wrapper_tests```.
Change to that directory and run ```tests_wrapper.py --help```.
Change to that directory and run ```tests_wrapper.py --help```; the test
suite gives a good set of examples of usage.
## Install
@ -78,3 +79,6 @@ Others include:
Hardcore C wrapping which is not easy to keep up to date.
No support for NGC or toxencryptsave. Abandonned.
This was the basis for the TokTok/py-toxcore-c code until recently.
To our point of view, the ability of CTYPEs to follow code in the
debugger is crucial.

View File

@ -3,7 +3,7 @@ import os
import sys
from ctypes import CDLL
# You need a libs directory beside this directory
# You need a libs directory beside this directory
# and you need to link your libtoxcore.so and libtoxav.so
# and libtoxencryptsave.so into ../libs/
# Link all 3 to libtoxcore.so if you have only libtoxcore.so
@ -13,7 +13,7 @@ try:
except ImportError:
sLIBS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
'libs')
class LibToxCore:
def __init__(self):
@ -40,11 +40,11 @@ class LibToxCore:
class LibToxAV:
def __init__(self):
platform = util.get_platform()
if platform == 'Windows':
platform = sys.platform
if platform == 'win32':
# on Windows av api is in libtox.dll
self._libtoxav = CDLL(os.path.join(sLIBS_DIR, 'libtox.dll'))
elif platform == 'Darwin':
elif platform == 'darwin':
self._libtoxav = CDLL('libtoxcore.dylib')
else:
libFile = os.path.join(sLIBS_DIR, 'libtoxav.so')

View File

@ -172,7 +172,7 @@ class Tox:
LOG_ERROR(f"tox_kill {e!s}")
else:
LOG_DEBUG(f"tox_kill")
# -----------------------------------------------------------------------------------------------------------------
# Startup options
# -----------------------------------------------------------------------------------------------------------------
@ -287,7 +287,7 @@ class Tox:
LOG_ERROR(f"libtoxcore.tox_bootstrap {e}")
# dunno
raise
tox_err_bootstrap = tox_err_bootstrap.value
if tox_err_bootstrap == TOX_ERR_BOOTSTRAP['OK']:
return bool(result)
@ -1341,7 +1341,7 @@ class Tox:
POINTER(None)())
self.file_recv_control_cb = None
return
LOG_DEBUG(f"tox_callback_file_recv_control")
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_int, c_void_p)
self.file_recv_control_cb = c_callback(callback)
@ -1607,7 +1607,7 @@ class Tox:
POINTER(None)())
self.file_recv_cb = None
return
LOG_DEBUG(f"tox_callback_file_recv")
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_uint32, c_uint64, c_char_p, c_size_t, c_void_p)
self.file_recv_cb = c_callback(callback)
@ -1640,7 +1640,7 @@ class Tox:
POINTER(None)())
self.file_recv_chunk_cb = None
return
LOG_DEBUG(f"tox_callback_file_recv_chunk")
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint32, c_uint64, POINTER(c_uint8), c_size_t, c_void_p)
self.file_recv_chunk_cb = c_callback(callback)
@ -1764,7 +1764,7 @@ class Tox:
self.friend_lossless_packet_cb = None
self.libtoxcore.tox_callback_friend_lossless_packet(self._tox_pointer, POINTER(None)())
return
LOG_DEBUG(f"callback_friend_lossless_packet")
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, POINTER(c_uint8), c_size_t, c_void_p)
self.friend_lossless_packet_cb = c_callback(callback)
@ -2387,7 +2387,6 @@ class Tox:
error = c_int()
buff = create_string_buffer(TOX_GROUP_CHAT_ID_SIZE)
LOG_DEBUG(f"tox_group_get_chat_id")
result = Tox.libtoxcore.tox_group_get_chat_id(self._tox_pointer,
group_number,
buff, byref(error))
@ -2575,23 +2574,27 @@ class Tox:
# -----------------------------------------------------------------------------------------------------------------
def group_send_custom_packet(self, group_number, lossless, data):
"""
Send a custom packet to the group.
"""Send a custom packet to the group.
If lossless is true the packet will be lossless. Lossless packet behaviour is comparable
to TCP (reliability, arrive in order) but with packets instead of a stream.
If lossless is true the packet will be lossless. Lossless
packet behaviour is comparable to TCP (reliability, arrive in
order) but with packets instead of a stream.
If lossless is false, the packet will be lossy. Lossy packets behave like UDP packets,
meaning they might never reach the other side or might arrive more than once (if someone
is messing with the connection) or might arrive in the wrong order.
If lossless is false, the packet will be lossy. Lossy packets
behave like UDP packets, meaning they might never reach the
other side or might arrive more than once (if someone is
messing with the connection) or might arrive in the wrong
order.
Unless latency is an issue or message reliability is not important, it is recommended that you use
lossless custom packets.
Unless latency is an issue or message reliability is not
important, it is recommended that you use lossless custom
packets.
:param group_number: The group number of the group the message is intended for.
:param lossless: True if the packet should be lossless.
:param data A byte array containing the packet data.
:return True on success.
"""
error = c_int()

View File

@ -391,7 +391,7 @@ class ToxAV:
self.libtoxav.toxav_callback_video_receive_frame(self._toxav_pointer, POINTER(None)(), user_data)
self.video_receive_frame_cb = None
return
LOG_DEBUG(f"toxav_callback_video_receive_frame")
c_callback = CFUNCTYPE(None, c_void_p, c_uint32, c_uint16, c_uint16,
POINTER(c_uint8), POINTER(c_uint8), POINTER(c_uint8),

View File

@ -518,23 +518,60 @@ def _get_nodes_path(oArgs=None):
DEFAULT_NODES_COUNT = 4
def generate_nodes(nodes_count=DEFAULT_NODES_COUNT, oArgs=None):
sFile = _get_nodes_path(oArgs=oArgs)
return generate_nodes_from_file(sFile, nodes_count)
def generate_nodes(
oArgs=None,
nodes_count=DEFAULT_NODES_COUNT,
ipv='ipv4',
udp_not_tcp=True):
if oArgs is None:
# Windwoes
sFile = os.path.join(os.getenv('HOME'), '.config', 'tox', 'DHTnodes.json')
else:
sFile = _get_nodes_path(oArgs=oArgs)
return generate_nodes_from_file(sFile,
nodes_count=nodes_count,
ipv=ipv, udp_not_tcp=udp_not_tcp)
def generate_nodes_from_file(sFile, nodes_count=DEFAULT_NODES_COUNT):
def generate_nodes_from_file(sFile,
nodes_count=DEFAULT_NODES_COUNT,
ipv='ipv4',
udp_not_tcp=True,
):
"""https://github.com/TokTok/c-toxcore/issues/469
I had a conversation with @irungentoo on IRC about whether we really need to call tox_bootstrap() when having UDP disabled and why. The answer is yes, because in addition to TCP relays (tox_add_tcp_relay()), toxcore also needs to know addresses of UDP onion nodes in order to work correctly. The DHT, however, is not used when UDP is disabled. tox_bootstrap() function resolves the address passed to it as argument and calls onion_add_bs_node_path() and DHT_bootstrap() functions. Although calling DHT_bootstrap() is not really necessary as DHT is not used, we still need to resolve the address of the DHT node in order to populate the onion routes with onion_add_bs_node_path() call.
"""
if not os.path.exists(sFile):
LOG.error("generate_nodes_from_file file not found " +sFile)
return []
LOG.info("generate_nodes_from_file " +sFile)
with open(sFile, 'rt') as fl:
json_nodes = json.loads(fl.read())['nodes']
nodes = [(node['ipv4'], node['port'], node['public_key'],) for
node in json_nodes if node['ipv4'] != 'NONE']
sorted_nodes = nodes
try:
with open(sFile, 'rt') as fl:
json_nodes = json.loads(fl.read())['nodes']
except Exception as e:
LOG.error(f"generate_nodes_from_file error {sFile}\n{e}")
return []
else:
LOG.info("generate_nodes_from_file " +sFile)
if udp_not_tcp:
nodes = [(node[ipv], node['port'], node['public_key'],) for
node in json_nodes if node[ipv] != 'NONE' \
and node["status_udp"] in [True, "true"]
]
else:
nodes = []
elts = [(node[ipv], node['tcp_ports'], node['public_key'],) \
for node in json_nodes if node[ipv] != 'NONE' \
and node['last_ping'] > 0
and node["status_tcp"] in [True, "true"]
]
for (ipv4, ports, public_key,) in elts:
for port in ports:
nodes += [(ipv4, port, public_key)]
sorted_nodes = sorted(nodes)
random.shuffle(sorted_nodes)
if nodes_count is not None and len(sorted_nodes) > nodes_count:
sorted_nodes = sorted_nodes[-nodes_count:]
LOG.debug(f"generate_nodes_from_file {sFile} len={len(sorted_nodes)}")
return sorted_nodes
def tox_bootstrapd_port():