Add zts_py_settimeout() and zts_py_gettimeout() methods; Update Python c extension bindings using swig -c++ -python zt.i

This commit is contained in:
Boston Walker
2021-12-27 23:58:24 -05:00
parent 13740f9767
commit 7e690785a4
5 changed files with 369 additions and 664 deletions

View File

@@ -489,6 +489,93 @@ done:
return res;
}
int zts_py_settimeout(int fd, PyObject* value)
{
int res;
// If None, set blocking mode
if (value == Py_None) {
res = zts_set_blocking(fd, true);
return res;
}
double double_val = PyFloat_AsDouble(value);
// If negative, throw an error
if (double_val < 0.) {
return ZTS_ERR_ARG;
}
// Set non-blocking mode
res = zts_set_blocking(fd, false);
if (res < 0) {
return res;
}
// Calculate timeout secs/microseconds
int total_micros = (int) floor(double_val * 1e6);
div_t div_res = div(total_micros, 1000);
int secs = div_res.quot;
int micros = div_res.rem;
// Set both send and recv timeouts
res = zts_set_send_timeout(fd, secs, micros);
if (res < 0) {
return res;
}
res = zts_set_recv_timeout(fd, secs, micros);
return res;
}
PyObject* zts_py_gettimeout(int fd)
{
PyObject *t;
int res;
t = PyTuple_New(2);
res = zts_get_blocking(fd);
// If err, return (err, None)
if (res < 0) {
PyTuple_SetItem(t, 0, PyLong_FromLong((long) res));
Py_INCREF(Py_None);
PyTuple_SetItem(t, 1, Py_None);
Py_INCREF(t);
return t;
}
// If socket in blocking mode, return (0, None)
if (res == 1) {
PyTuple_SetItem(t, 0, PyLong_FromLong(0L));
Py_INCREF(Py_None);
PyTuple_SetItem(t, 1, Py_None);
Py_INCREF(t);
return t;
}
// Send and recv timeouts should be equal
res = zts_get_recv_timeout(fd);
// If err, return (err, None)
if (res < 0) {
PyTuple_SetItem(t, 0, PyLong_FromLong((long) res));
Py_INCREF(Py_None);
PyTuple_SetItem(t, 1, Py_None);
Py_INCREF(t);
return t;
}
// Return (0, timeout)
// Result of zts_get_recv_timeout() is in milliseconds
double timeout = 1e-3 * (double) res;
PyTuple_SetItem(t, 0, PyLong_FromLong(0L));
PyTuple_SetItem(t, 1, PyFloat_FromDouble(timeout));
Py_INCREF(t);
return t;
}
PyObject* zts_py_getsockopt(int fd, PyObject* args)
{
int level;

View File

@@ -39,6 +39,10 @@ int zts_py_setsockopt(int fd, PyObject* args);
PyObject* zts_py_getsockopt(int fd, PyObject* args);
int zts_py_settimeout(int fd, PyObject* value);
PyObject* zts_py_gettimeout(int fd);
#endif // ZTS_ENABLE_PYTHON
#endif // ZTS_PYTHON_SOCKETS_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
"""ZeroTier low-level socket interface"""
import libzt
@@ -421,8 +420,39 @@ class socket:
libzt.zts_set_blocking(self._fd, flag)
def settimeout(self, value):
"""libzt does not support this (yet)"""
raise NotImplementedError("libzt does not support this (yet?)")
"""
|Set timeout for socket send/recv operations. Socket can be in one of three modes:
| - Blocking: Operations block until complete or the system returns an error (e.g. connection timed out)
| - Non-blocking: Operations fail if they cannot be completed immediately
| - Timeout: Operations fail if they cannot be completed within the specified timeout (and raise TimeoutError)
:param value: Timeout in seconds (must be non-negative).
If zero, socket is put in non-blocking mode.
If None, socket is put in blocking mode.
:type value: Float
:return: None
"""
err = libzt.zts_py_settimeout(self._fd, value)
if err < 0:
handle_error(err)
def gettimeout(self):
"""
|Get timeout for socket send/recv operations. Socket can be in one of three modes:
| - Blocking: Operations block until complete or the system returns an error (e.g. connection timed out)
| - Non-blocking: Operations fail if they cannot be completed immediately
| - Timeout: Operations fail if they cannot be completed within the specified timeout (and raise TimeoutError)
:return: Timeout in seconds.
If zero, socket is in non-blocking mode.
If None, socket is in blocking mode.
:rtype: Optional[float]
"""
err, res = libzt.zts_py_gettimeout(self._fd)
if err < 0:
handle_error(err)
else:
return res
def setsockopt(self, level, optname, value):
"""Set a socket option value"""

View File

@@ -15637,36 +15637,6 @@ fail:
}
SWIGINTERN PyObject *_wrap_zts_py_listen(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
int arg2 ;
int val1 ;
int ecode1 = 0 ;
int val2 ;
int ecode2 = 0 ;
PyObject *swig_obj[2] ;
int result;
if (!SWIG_Python_UnpackTuple(args, "zts_py_listen", 2, 2, swig_obj)) SWIG_fail;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_listen" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_py_listen" "', argument " "2"" of type '" "int""'");
}
arg2 = static_cast< int >(val2);
result = (int)zts_py_listen(arg1,arg2);
resultobj = SWIG_From_int(static_cast< int >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_recv(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
@@ -15760,59 +15730,6 @@ fail:
}
SWIGINTERN PyObject *_wrap_zts_py_setblocking(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
int arg2 ;
int val1 ;
int ecode1 = 0 ;
int val2 ;
int ecode2 = 0 ;
PyObject *swig_obj[2] ;
int result;
if (!SWIG_Python_UnpackTuple(args, "zts_py_setblocking", 2, 2, swig_obj)) SWIG_fail;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_setblocking" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);
if (!SWIG_IsOK(ecode2)) {
SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "zts_py_setblocking" "', argument " "2"" of type '" "int""'");
}
arg2 = static_cast< int >(val2);
result = (int)zts_py_setblocking(arg1,arg2);
resultobj = SWIG_From_int(static_cast< int >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_getblocking(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
int val1 ;
int ecode1 = 0 ;
PyObject *swig_obj[1] ;
int result;
if (!args) SWIG_fail;
swig_obj[0] = args;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_getblocking" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
result = (int)zts_py_getblocking(arg1);
resultobj = SWIG_From_int(static_cast< int >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_addr_get_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
uint64_t arg1 ;
@@ -15843,6 +15760,125 @@ fail:
}
SWIGINTERN PyObject *_wrap_zts_py_select(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
PyObject *arg1 = (PyObject *) 0 ;
PyObject *arg2 = (PyObject *) 0 ;
PyObject *arg3 = (PyObject *) 0 ;
PyObject *arg4 = (PyObject *) 0 ;
PyObject *arg5 = (PyObject *) 0 ;
PyObject *swig_obj[5] ;
PyObject *result = 0 ;
if (!SWIG_Python_UnpackTuple(args, "zts_py_select", 5, 5, swig_obj)) SWIG_fail;
arg1 = swig_obj[0];
arg2 = swig_obj[1];
arg3 = swig_obj[2];
arg4 = swig_obj[3];
arg5 = swig_obj[4];
result = (PyObject *)zts_py_select(arg1,arg2,arg3,arg4,arg5);
resultobj = result;
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_setsockopt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
PyObject *arg2 = (PyObject *) 0 ;
int val1 ;
int ecode1 = 0 ;
PyObject *swig_obj[2] ;
int result;
if (!SWIG_Python_UnpackTuple(args, "zts_py_setsockopt", 2, 2, swig_obj)) SWIG_fail;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_setsockopt" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
arg2 = swig_obj[1];
result = (int)zts_py_setsockopt(arg1,arg2);
resultobj = SWIG_From_int(static_cast< int >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_getsockopt(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
PyObject *arg2 = (PyObject *) 0 ;
int val1 ;
int ecode1 = 0 ;
PyObject *swig_obj[2] ;
PyObject *result = 0 ;
if (!SWIG_Python_UnpackTuple(args, "zts_py_getsockopt", 2, 2, swig_obj)) SWIG_fail;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_getsockopt" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
arg2 = swig_obj[1];
result = (PyObject *)zts_py_getsockopt(arg1,arg2);
resultobj = result;
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_settimeout(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
PyObject *arg2 = (PyObject *) 0 ;
int val1 ;
int ecode1 = 0 ;
PyObject *swig_obj[2] ;
int result;
if (!SWIG_Python_UnpackTuple(args, "zts_py_settimeout", 2, 2, swig_obj)) SWIG_fail;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_settimeout" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
arg2 = swig_obj[1];
result = (int)zts_py_settimeout(arg1,arg2);
resultobj = SWIG_From_int(static_cast< int >(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_zts_py_gettimeout(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
int arg1 ;
int val1 ;
int ecode1 = 0 ;
PyObject *swig_obj[1] ;
PyObject *result = 0 ;
if (!args) SWIG_fail;
swig_obj[0] = args;
ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
if (!SWIG_IsOK(ecode1)) {
SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "zts_py_gettimeout" "', argument " "1"" of type '" "int""'");
}
arg1 = static_cast< int >(val1);
result = (PyObject *)zts_py_gettimeout(arg1);
resultobj = result;
return resultobj;
fail:
return NULL;
}
static PyMethodDef SwigMethods[] = {
{ "SWIG_PyInstanceMethod_New", SWIG_PyInstanceMethod_New, METH_O, NULL},
{ "zts_node_info_t_node_id_set", _wrap_zts_node_info_t_node_id_set, METH_VARARGS, NULL},
@@ -16293,13 +16329,15 @@ static PyMethodDef SwigMethods[] = {
{ "zts_py_bind", _wrap_zts_py_bind, METH_VARARGS, NULL},
{ "zts_py_connect", _wrap_zts_py_connect, METH_VARARGS, NULL},
{ "zts_py_accept", _wrap_zts_py_accept, METH_O, NULL},
{ "zts_py_listen", _wrap_zts_py_listen, METH_VARARGS, NULL},
{ "zts_py_recv", _wrap_zts_py_recv, METH_VARARGS, NULL},
{ "zts_py_send", _wrap_zts_py_send, METH_VARARGS, NULL},
{ "zts_py_close", _wrap_zts_py_close, METH_O, NULL},
{ "zts_py_setblocking", _wrap_zts_py_setblocking, METH_VARARGS, NULL},
{ "zts_py_getblocking", _wrap_zts_py_getblocking, METH_O, NULL},
{ "zts_py_addr_get_str", _wrap_zts_py_addr_get_str, METH_VARARGS, NULL},
{ "zts_py_select", _wrap_zts_py_select, METH_VARARGS, NULL},
{ "zts_py_setsockopt", _wrap_zts_py_setsockopt, METH_VARARGS, NULL},
{ "zts_py_getsockopt", _wrap_zts_py_getsockopt, METH_VARARGS, NULL},
{ "zts_py_settimeout", _wrap_zts_py_settimeout, METH_VARARGS, NULL},
{ "zts_py_gettimeout", _wrap_zts_py_gettimeout, METH_O, NULL},
{ NULL, NULL, 0, NULL }
};
@@ -16313,7 +16351,7 @@ static PyMethodDef SwigMethods_proxydocs[] = {
static swig_type_info _swigt__p_PythonDirectorCallbackClass = {"_p_PythonDirectorCallbackClass", "PythonDirectorCallbackClass *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_a_32__p_char = {"_p_a_32__p_char", "char *(*)[32]", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|SOCKET_T *|int_fast16_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0};
@@ -17315,6 +17353,7 @@ SWIG_init(void) {
SWIG_Python_SetConstant(d, "ZTS_EISCONN",SWIG_From_int(static_cast< int >(ZTS_EISCONN)));
SWIG_Python_SetConstant(d, "ZTS_ENOTCONN",SWIG_From_int(static_cast< int >(ZTS_ENOTCONN)));
SWIG_Python_SetConstant(d, "ZTS_ETIMEDOUT",SWIG_From_int(static_cast< int >(ZTS_ETIMEDOUT)));
SWIG_Python_SetConstant(d, "ZTS_ECONNREFUSED",SWIG_From_int(static_cast< int >(ZTS_ECONNREFUSED)));
SWIG_Python_SetConstant(d, "ZTS_EHOSTUNREACH",SWIG_From_int(static_cast< int >(ZTS_EHOSTUNREACH)));
SWIG_Python_SetConstant(d, "ZTS_EALREADY",SWIG_From_int(static_cast< int >(ZTS_EALREADY)));
SWIG_Python_SetConstant(d, "ZTS_EINPROGRESS",SWIG_From_int(static_cast< int >(ZTS_EINPROGRESS)));