Add address getter method to Python wrapper

This commit is contained in:
Joseph Henry
2021-05-19 21:33:08 -07:00
parent 111dc7f5d9
commit 4e0813d167
11 changed files with 15884 additions and 21731 deletions

View File

@@ -661,8 +661,11 @@ format-code()
if [[ $1 = *"python"* ]]; then if [[ $1 = *"python"* ]]; then
if [[ ! $($PIP list | grep black) = "" ]]; if [[ ! $($PIP list | grep black) = "" ]];
then then
$PYTHON -m black src/bindings/python/*.py $PYTHON -m black src/bindings/python/libzt.py
$PYTHON -m black examples/python/*.py $PYTHON -m black src/bindings/python/node.py
$PYTHON -m black src/bindings/python/sockets.py
$PYTHON -m black examples/python/
$PYTHON -m black test/selftest.py
else else
echo "Please install python module (black)" echo "Please install python module (black)"
fi fi

View File

@@ -996,48 +996,6 @@ typedef struct {
int len; int len;
} zts_event_msg_t; } zts_event_msg_t;
//----------------------------------------------------------------------------//
// Python Bindings (Subset of regular socket API) //
//----------------------------------------------------------------------------//
#ifdef ZTS_ENABLE_PYTHON
#include "Python.h"
/**
* Abstract class used as a director. Pointer to an instance of this class
* is provided to the Python layer.
*/
class PythonDirectorCallbackClass {
public:
/**
* Called by native code on event. Implemented in Python
*/
virtual void on_zerotier_event(zts_event_msg_t* msg);
virtual ~PythonDirectorCallbackClass() {};
};
extern PythonDirectorCallbackClass* _userEventCallback;
int zts_py_bind(int fd, int family, int type, PyObject* addro);
int zts_py_connect(int fd, int family, int type, PyObject* addro);
PyObject* zts_py_accept(int fd);
int zts_py_listen(int fd, int backlog);
PyObject* zts_py_recv(int fd, int len, int flags);
int zts_py_send(int fd, PyObject* buf, int flags);
int zts_py_close(int fd);
int zts_py_setblocking(int fd, int flag);
int zts_py_getblocking(int fd);
#endif // ZTS_ENABLE_PYTHON
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
// ZeroTier Service and Network Controls // // ZeroTier Service and Network Controls //
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
@@ -1274,6 +1232,24 @@ ZTS_API int ZTCALL zts_init_from_storage(const char* path);
*/ */
ZTS_API int ZTCALL zts_init_from_memory(const char* key, unsigned int len); ZTS_API int ZTCALL zts_init_from_memory(const char* key, unsigned int len);
#ifdef ZTS_ENABLE_PYTHON
#include "Python.h"
/**
* Abstract class used as a director. Pointer to an instance of this class
* is provided to the Python layer.
*/
class PythonDirectorCallbackClass {
public:
/**
* Called by native code on event. Implemented in Python
*/
virtual void on_zerotier_event(zts_event_msg_t* msg);
virtual ~PythonDirectorCallbackClass() {};
};
extern PythonDirectorCallbackClass* _userEventCallback;
/** /**
* @brief Set the event handler function. This is an initialization function that can only be called * @brief Set the event handler function. This is an initialization function that can only be called
* before `zts_node_start()`. * before `zts_node_start()`.
@@ -1283,7 +1259,6 @@ ZTS_API int ZTCALL zts_init_from_memory(const char* key, unsigned int len);
* @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node * @return `ZTS_ERR_OK` if successful, `ZTS_ERR_SERVICE` if the node
* experiences a problem, `ZTS_ERR_ARG` if invalid argument. * experiences a problem, `ZTS_ERR_ARG` if invalid argument.
*/ */
#ifdef ZTS_ENABLE_PYTHON
ZTS_API int ZTCALL zts_init_set_event_handler(PythonDirectorCallbackClass* callback); ZTS_API int ZTCALL zts_init_set_event_handler(PythonDirectorCallbackClass* callback);
#endif #endif
#ifdef ZTS_ENABLE_PINVOKE #ifdef ZTS_ENABLE_PINVOKE

View File

@@ -110,8 +110,7 @@ setup(
keywords = 'zerotier p2p peer-to-peer sdwan sdn virtual network socket tcp udp zt encryption encrypted', keywords = 'zerotier p2p peer-to-peer sdwan sdn virtual network socket tcp udp zt encryption encrypted',
py_modules = ['libzt'], py_modules = ['libzt'],
packages = ['libzt'], packages = ['libzt'],
classifiers = ['Development Status :: 4 - Beta', classifiers = ['Topic :: Internet',
'Topic :: Internet',
'Topic :: System :: Networking', 'Topic :: System :: Networking',
'Topic :: Security :: Cryptography', 'Topic :: Security :: Cryptography',
'Intended Audience :: Developers', 'Intended Audience :: Developers',

View File

@@ -200,4 +200,15 @@ int zts_py_close(int fd)
Py_END_ALLOW_THREADS return err; Py_END_ALLOW_THREADS return err;
} }
PyObject* zts_py_addr_get_str(uint64_t net_id, int family)
{
char addr_str[ZTS_IP_MAX_STR_LEN] = { 0 };
if (zts_addr_get_str(net_id, family, addr_str, ZTS_IP_MAX_STR_LEN) < 0) {
PyErr_SetString(PyExc_Warning, "No address of the given type has been assigned by the network");
return NULL;
}
PyObject* t = PyUnicode_FromString(addr_str);
return t;
}
#endif // ZTS_ENABLE_PYTHON #endif // ZTS_ENABLE_PYTHON

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c)2013-2021 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2026-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
#ifndef ZTS_PYTHON_SOCKETS_H
#define ZTS_PYTHON_SOCKETS_H
#ifdef ZTS_ENABLE_PYTHON
#include "Python.h"
int zts_py_bind(int fd, int family, int type, PyObject* addro);
int zts_py_connect(int fd, int family, int type, PyObject* addro);
PyObject* zts_py_accept(int fd);
int zts_py_listen(int fd, int backlog);
PyObject* zts_py_recv(int fd, int len, int flags);
int zts_py_send(int fd, PyObject* buf, int flags);
int zts_py_close(int fd);
int zts_py_setblocking(int fd, int flag);
int zts_py_getblocking(int fd);
PyObject* zts_py_addr_get_str(uint64_t net_id, int family);
#endif // ZTS_ENABLE_PYTHON
#endif // ZTS_PYTHON_SOCKETS_H

View File

@@ -532,6 +532,25 @@ class zts_event_msg_t(object):
# Register zts_event_msg_t in _libzt: # Register zts_event_msg_t in _libzt:
_libzt.zts_event_msg_t_swigregister(zts_event_msg_t) _libzt.zts_event_msg_t_swigregister(zts_event_msg_t)
ZTS_DISABLE_CENTRAL_API = _libzt.ZTS_DISABLE_CENTRAL_API
ZTS_ID_STR_BUF_LEN = _libzt.ZTS_ID_STR_BUF_LEN
def zts_id_new(key, key_buf_len):
return _libzt.zts_id_new(key, key_buf_len)
def zts_id_pair_is_valid(key, len):
return _libzt.zts_id_pair_is_valid(key, len)
def zts_init_from_storage(path):
return _libzt.zts_init_from_storage(path)
def zts_init_from_memory(key, len):
return _libzt.zts_init_from_memory(key, len)
class PythonDirectorCallbackClass(object): class PythonDirectorCallbackClass(object):
thisown = property( thisown = property(
@@ -566,62 +585,6 @@ class PythonDirectorCallbackClass(object):
_libzt.PythonDirectorCallbackClass_swigregister(PythonDirectorCallbackClass) _libzt.PythonDirectorCallbackClass_swigregister(PythonDirectorCallbackClass)
def zts_py_bind(fd, family, type, addro):
return _libzt.zts_py_bind(fd, family, type, addro)
def zts_py_connect(fd, family, type, addro):
return _libzt.zts_py_connect(fd, family, type, addro)
def zts_py_accept(fd):
return _libzt.zts_py_accept(fd)
def zts_py_listen(fd, backlog):
return _libzt.zts_py_listen(fd, backlog)
def zts_py_recv(fd, len, flags):
return _libzt.zts_py_recv(fd, len, flags)
def zts_py_send(fd, buf, flags):
return _libzt.zts_py_send(fd, buf, flags)
def zts_py_close(fd):
return _libzt.zts_py_close(fd)
def zts_py_setblocking(fd, flag):
return _libzt.zts_py_setblocking(fd, flag)
def zts_py_getblocking(fd):
return _libzt.zts_py_getblocking(fd)
ZTS_DISABLE_CENTRAL_API = _libzt.ZTS_DISABLE_CENTRAL_API
ZTS_ID_STR_BUF_LEN = _libzt.ZTS_ID_STR_BUF_LEN
def zts_id_new(key, key_buf_len):
return _libzt.zts_id_new(key, key_buf_len)
def zts_id_pair_is_valid(key, len):
return _libzt.zts_id_pair_is_valid(key, len)
def zts_init_from_storage(path):
return _libzt.zts_init_from_storage(path)
def zts_init_from_memory(key, len):
return _libzt.zts_init_from_memory(key, len)
def zts_init_set_event_handler(callback): def zts_init_set_event_handler(callback):
return _libzt.zts_init_set_event_handler(callback) return _libzt.zts_init_set_event_handler(callback)
@@ -1509,3 +1472,43 @@ def zts_inet_ntop(family, src, dst, size):
def zts_inet_pton(family, src, dst): def zts_inet_pton(family, src, dst):
return _libzt.zts_inet_pton(family, src, dst) return _libzt.zts_inet_pton(family, src, dst)
def zts_py_bind(fd, family, type, addro):
return _libzt.zts_py_bind(fd, family, type, addro)
def zts_py_connect(fd, family, type, addro):
return _libzt.zts_py_connect(fd, family, type, addro)
def zts_py_accept(fd):
return _libzt.zts_py_accept(fd)
def zts_py_listen(fd, backlog):
return _libzt.zts_py_listen(fd, backlog)
def zts_py_recv(fd, len, flags):
return _libzt.zts_py_recv(fd, len, flags)
def zts_py_send(fd, buf, flags):
return _libzt.zts_py_send(fd, buf, flags)
def zts_py_close(fd):
return _libzt.zts_py_close(fd)
def zts_py_setblocking(fd, flag):
return _libzt.zts_py_setblocking(fd, flag)
def zts_py_getblocking(fd):
return _libzt.zts_py_getblocking(fd)
def zts_py_addr_get_str(net_id, family):
return _libzt.zts_py_addr_get_str(net_id, family)

View File

@@ -77,3 +77,9 @@ class ZeroTierNode:
def net_transport_is_ready(self, net_id): def net_transport_is_ready(self, net_id):
return libzt.zts_net_transport_is_ready(net_id) return libzt.zts_net_transport_is_ready(net_id)
def addr_get_ipv4(self, net_id):
return libzt.zts_py_addr_get_str(net_id, libzt.ZTS_AF_INET)
def addr_get_ipv6(self, net_id):
return libzt.zts_py_addr_get_str(net_id, libzt.ZTS_AF_INET6)

View File

@@ -13,6 +13,7 @@
%module libzt %module libzt
%{ %{
#include "ZeroTierSockets.h" #include "ZeroTierSockets.h"
#include "PythonSockets.h"
%} %}
%feature("director") PythonDirectorCallbackClass; %feature("director") PythonDirectorCallbackClass;
@@ -35,3 +36,4 @@
%ignore zts_msghdr; %ignore zts_msghdr;
%include "ZeroTierSockets.h" %include "ZeroTierSockets.h"
%include "PythonSockets.h"

File diff suppressed because it is too large Load Diff

View File

@@ -14,38 +14,34 @@
#include <map> #include <map>
#include <string> #include <string>
class SwigDirector_PythonDirectorCallbackClass
: public PythonDirectorCallbackClass class SwigDirector_PythonDirectorCallbackClass : public PythonDirectorCallbackClass, public Swig::Director {
, public Swig::Director {
public: public:
SwigDirector_PythonDirectorCallbackClass(PyObject* self); SwigDirector_PythonDirectorCallbackClass(PyObject *self);
virtual void on_zerotier_event(zts_event_msg_t* msg); virtual void on_zerotier_event(zts_event_msg_t *msg);
virtual ~SwigDirector_PythonDirectorCallbackClass(); virtual ~SwigDirector_PythonDirectorCallbackClass();
/* Internal director utilities */ /* Internal director utilities */
public: public:
bool swig_get_inner(const char* swig_protected_method_name) const bool swig_get_inner(const char *swig_protected_method_name) const {
{
std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name); std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);
return (iv != swig_inner.end() ? iv->second : false); return (iv != swig_inner.end() ? iv->second : false);
} }
void swig_set_inner(const char* swig_protected_method_name, bool swig_val) const void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {
{
swig_inner[swig_protected_method_name] = swig_val; swig_inner[swig_protected_method_name] = swig_val;
} }
private:
private:
mutable std::map<std::string, bool> swig_inner; mutable std::map<std::string, bool> swig_inner;
#if defined(SWIG_PYTHON_DIRECTOR_VTABLE) #if defined(SWIG_PYTHON_DIRECTOR_VTABLE)
/* VTable implementation */ /* VTable implementation */
PyObject* swig_get_method(size_t method_index, const char* method_name) const PyObject *swig_get_method(size_t method_index, const char *method_name) const {
{ PyObject *method = vtable[method_index];
PyObject* method = vtable[method_index]; if (!method) {
if (! method) {
swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name); swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);
method = PyObject_GetAttr(swig_get_self(), name); method = PyObject_GetAttr(swig_get_self(), name);
if (! method) { if (!method) {
std::string msg = "Method in class PythonDirectorCallbackClass doesn't exist, undefined "; std::string msg = "Method in class PythonDirectorCallbackClass doesn't exist, undefined ";
msg += method_name; msg += method_name;
Swig::DirectorMethodException::raise(msg.c_str()); Swig::DirectorMethodException::raise(msg.c_str());
@@ -54,10 +50,11 @@ class SwigDirector_PythonDirectorCallbackClass
} }
return method; return method;
} }
private:
private:
mutable swig::SwigVar_PyObject vtable[1]; mutable swig::SwigVar_PyObject vtable[1];
#endif #endif
}; };
#endif #endif

View File

@@ -89,6 +89,8 @@ def main():
time.sleep(1) time.sleep(1)
print("Joined network") print("Joined network")
print("addr = ", n.addr_get_ipv4(net_id))
# #
# Example server # Example server
# #