enhanced nwad functions
This commit is contained in:
@ -24,121 +24,83 @@
|
||||
#include <qse/cmn/fmt.h>
|
||||
#include "mem.h"
|
||||
|
||||
#if 0
|
||||
int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad)
|
||||
#if defined(HAVE_NET_IF_H)
|
||||
#include <net/if.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
|
||||
#if !defined(IF_NAMESIZE)
|
||||
# define IF_NAMESIZE 63
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IF_NAMETOINDEX)
|
||||
static QSE_INLINE unsigned int mbsn_to_ifindex (const qse_mchar_t* ptr, qse_size_t len)
|
||||
{
|
||||
const qse_mchar_t* p;
|
||||
qse_mcstr_t tmp;
|
||||
qse_nwad_t tmpad;
|
||||
|
||||
QSE_MEMSET (&tmpad, 0, QSE_SIZEOF(tmpad));
|
||||
|
||||
p = str;
|
||||
if (*p == QSE_MT('['))
|
||||
qse_mchar_t tmp[IF_NAMESIZE + 1];
|
||||
if (qse_mbsxncpy (tmp, QSE_COUNTOF(tmp), ptr, len) < len)
|
||||
{
|
||||
/* IPv6 address */
|
||||
tmp.ptr = ++p; /* skip [ and remember the position */
|
||||
while (*p != QSE_MT('\0') && *p != QSE_MT('%') && *p != QSE_MT(']')) p++;
|
||||
|
||||
if (*p == QSE_MT('\0')) return -1;
|
||||
|
||||
tmp.len = p - tmp.ptr;
|
||||
if (*p == QSE_MT('%'))
|
||||
{
|
||||
/* handle scope id */
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (!(*p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1;
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (*p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
|
||||
if (*p != QSE_MT(']')) return -1;
|
||||
}
|
||||
p++; /* skip ] */
|
||||
|
||||
if (qse_mbsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1) return -1;
|
||||
tmpad.type = QSE_NWAD_IN6;
|
||||
/* name too long */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* host name or IPv4 address */
|
||||
tmp.ptr = p;
|
||||
while (*p != QSE_MT('\0') && *p != QSE_MT(':')) p++;
|
||||
tmp.len = p - tmp.ptr;
|
||||
return if_nametoindex (tmp);
|
||||
}
|
||||
|
||||
if (qse_mbsntoipad4 (tmp.ptr, tmp.len, &tmpad.u.in4.addr) <= -1)
|
||||
{
|
||||
/* check if it is an IPv6 address not enclosed in [].
|
||||
* the port number can't be specified in this format. */
|
||||
static QSE_INLINE unsigned int wcsn_to_ifindex (const qse_wchar_t* ptr, qse_size_t len)
|
||||
{
|
||||
qse_mchar_t tmp[IF_NAMESIZE + 1];
|
||||
qse_size_t wl, ml;
|
||||
|
||||
while (*p != QSE_MT('\0') && *p != QSE_MT('%')) p++;
|
||||
tmp.len = p - tmp.ptr;
|
||||
wl = len; ml = QSE_COUNTOF(tmp) - 1;
|
||||
if (qse_wcsntombsn (ptr, &wl, tmp, &ml) <= -1) return 0;
|
||||
tmp[ml] = QSE_MT('\0');
|
||||
return if_nametoindex (tmp);
|
||||
}
|
||||
#else
|
||||
staitc QSE_INLINE unsigned int mbsn_to_ifindex (const qse_mchar_t* ptr, qse_size_t len)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
staitc QSE_INLINE unsigned int wcsn_to_ifindex (const qse_wchar_t* ptr, qse_size_t len)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (qse_mbsntoipad6 (tmp.ptr, tmp.len, &tmpad.u.in6.addr) <= -1)
|
||||
return -1;
|
||||
#if defined(HAVE_IF_INDEXTONAME)
|
||||
static QSE_INLINE int ifindex_to_mbsn (unsigned int index, qse_mchar_t* buf, qse_size_t len)
|
||||
{
|
||||
qse_mchar_t tmp[IF_NAMESIZE + 1];
|
||||
if (if_indextoname (index, tmp) == QSE_NULL) return 0;
|
||||
return qse_mbsxcpy (buf, len, tmp);
|
||||
}
|
||||
|
||||
if (*p == QSE_MT('%'))
|
||||
{
|
||||
/* handle scope id */
|
||||
qse_uint32_t x;
|
||||
static QSE_INLINE int ifindex_to_wcsn (unsigned int index, qse_wchar_t* buf, qse_size_t len)
|
||||
{
|
||||
qse_mchar_t tmp[IF_NAMESIZE + 1];
|
||||
qse_size_t ml, wl;
|
||||
int x;
|
||||
|
||||
p++; /* skip % */
|
||||
if (!(*p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1;
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (*p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
}
|
||||
if (if_indextoname (index, tmp) == QSE_NULL) return 0;
|
||||
wl = len;
|
||||
x = qse_mbstowcs (tmp, &ml, buf, &wl);
|
||||
if (x == -2 && wl > 1) buf[wl - 1] = QSE_WT('\0');
|
||||
else if (x != 0) return 0;
|
||||
return wl;
|
||||
}
|
||||
|
||||
if (*p != QSE_MT('\0')) return -1;
|
||||
|
||||
tmpad.type = QSE_NWAD_IN6;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tmpad.type = QSE_NWAD_IN4;
|
||||
}
|
||||
|
||||
if (*p == QSE_MT(':'))
|
||||
{
|
||||
/* port number */
|
||||
qse_uint32_t port = 0;
|
||||
|
||||
p++; /* skip : */
|
||||
|
||||
for (tmp.ptr = p; *p >= QSE_MT('0') && *p <= QSE_MT('9'); p++)
|
||||
port = port * 10 + (*p - QSE_MT('0'));
|
||||
|
||||
tmp.len = p - tmp.ptr;
|
||||
if (tmp.len <= 0 || tmp.len >= 6 ||
|
||||
port > QSE_TYPE_MAX(qse_uint16_t)) return -1;
|
||||
|
||||
if (tmpad.type == QSE_NWAD_IN4)
|
||||
tmpad.u.in4.port = qse_hton16 (port);
|
||||
else
|
||||
tmpad.u.in6.port = qse_hton16 (port);
|
||||
}
|
||||
|
||||
done:
|
||||
if (nwad) *nwad = tmpad;
|
||||
#else
|
||||
static QSE_INLINE int ifindex_to_mbsn (unsigned int index, qse_mchar_t* buf, qse_size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static QSE_INLINE int ifindex_to_wcsn (unsigned int index, qse_wchar_t* buf, qse_size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad)
|
||||
{
|
||||
return qse_mbsntonwad (str, qse_mbslen(str), nwad);
|
||||
@ -174,16 +136,33 @@ int qse_mbsntonwad (const qse_mchar_t* str, qse_size_t len, qse_nwad_t* nwad)
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (!(p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1;
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
if (p >= end)
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_MT('0') && *p <= QSE_MT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_mchar_t* stmp = p;
|
||||
do p++; while (p < end && *p != QSE_MT(']'));
|
||||
tmpad.u.in6.scope = mbsn_to_ifindex (stmp, p - stmp);
|
||||
if (tmpad.u.in6.scope <= 0) return -1;
|
||||
}
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
|
||||
if (p >= end || *p != QSE_MT(']')) return -1;
|
||||
}
|
||||
@ -218,16 +197,34 @@ int qse_mbsntonwad (const qse_mchar_t* str, qse_size_t len, qse_nwad_t* nwad)
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
if (!(p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'))) return -1;
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
|
||||
if (p >= end)
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_MT('0') && *p <= QSE_MT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_MT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_mchar_t* stmp = p;
|
||||
do p++; while (p < end);
|
||||
tmpad.u.in6.scope = mbsn_to_ifindex (stmp, p - stmp);
|
||||
if (tmpad.u.in6.scope <= 0) return -1;
|
||||
}
|
||||
while (p < end && *p >= QSE_MT('0') && *p <= QSE_MT('9'));
|
||||
}
|
||||
|
||||
if (p < end) return -1;
|
||||
@ -303,16 +300,33 @@ int qse_wcsntonwad (const qse_wchar_t* str, qse_size_t len, qse_nwad_t* nwad)
|
||||
|
||||
p++; /* skip % */
|
||||
|
||||
if (!(p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'))) return -1;
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
if (p >= end)
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_WT('0') && *p <= QSE_WT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_wchar_t* stmp = p;
|
||||
do p++; while (p < end && *p != QSE_WT(']'));
|
||||
tmpad.u.in6.scope = wcsn_to_ifindex (stmp, p - stmp);
|
||||
if (tmpad.u.in6.scope <= 0) return -1;
|
||||
}
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'));
|
||||
|
||||
if (p >= end || *p != QSE_WT(']')) return -1;
|
||||
}
|
||||
@ -347,16 +361,34 @@ int qse_wcsntonwad (const qse_wchar_t* str, qse_size_t len, qse_nwad_t* nwad)
|
||||
qse_uint32_t x;
|
||||
|
||||
p++; /* skip % */
|
||||
if (!(p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'))) return -1;
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
|
||||
if (p >= end)
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
/* premature end */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p >= QSE_WT('0') && *p <= QSE_WT('9'))
|
||||
{
|
||||
/* numeric scope id */
|
||||
tmpad.u.in6.scope = 0;
|
||||
do
|
||||
{
|
||||
x = tmpad.u.in6.scope * 10 + (*p - QSE_WT('0'));
|
||||
if (x < tmpad.u.in6.scope) return -1; /* overflow */
|
||||
tmpad.u.in6.scope = x;
|
||||
p++;
|
||||
}
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* interface name as a scope id? */
|
||||
const qse_wchar_t* stmp = p;
|
||||
do p++; while (p < end);
|
||||
tmpad.u.in6.scope = wcsn_to_ifindex (stmp, p - stmp);
|
||||
if (tmpad.u.in6.scope <= 0) return -1;
|
||||
}
|
||||
while (p < end && *p >= QSE_WT('0') && *p <= QSE_WT('9'));
|
||||
}
|
||||
|
||||
if (p < end) return -1;
|
||||
@ -446,18 +478,27 @@ qse_size_t qse_nwadtombs (
|
||||
|
||||
if (flags & QSE_NWADTOMBS_ADDR)
|
||||
{
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_ipad6tombs (&nwad->u.in6.addr, &buf[xlen], len - xlen);
|
||||
|
||||
if (nwad->u.in6.scope != 0)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_MT('%');
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_fmtuintmaxtombs (
|
||||
&buf[xlen], len - xlen,
|
||||
nwad->u.in6.scope, 10, 0, QSE_MT('\0'), QSE_NULL);
|
||||
|
||||
tmp = ifindex_to_mbsn (nwad->u.in6.scope, &buf[xlen], len - xlen);
|
||||
if (tmp <= 0)
|
||||
{
|
||||
xlen += qse_fmtuintmaxtombs (
|
||||
&buf[xlen], len - xlen,
|
||||
nwad->u.in6.scope, 10, 0, QSE_MT('\0'), QSE_NULL);
|
||||
}
|
||||
else xlen += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,13 +588,21 @@ qse_size_t qse_nwadtowcs (
|
||||
|
||||
if (nwad->u.in6.scope != 0)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
buf[xlen++] = QSE_WT('%');
|
||||
|
||||
if (xlen + 1 >= len) goto done;
|
||||
xlen += qse_fmtuintmaxtowcs (
|
||||
&buf[xlen], len - xlen,
|
||||
nwad->u.in6.scope, 10, 0, QSE_WT('\0'), QSE_NULL);
|
||||
|
||||
tmp = ifindex_to_wcsn (nwad->u.in6.scope, &buf[xlen], len - xlen);
|
||||
if (tmp <= 0)
|
||||
{
|
||||
xlen += qse_fmtuintmaxtowcs (
|
||||
&buf[xlen], len - xlen,
|
||||
nwad->u.in6.scope, 10, 0, QSE_WT('\0'), QSE_NULL);
|
||||
}
|
||||
else xlen += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,14 +437,18 @@ int qse_nwio_init (
|
||||
return -1;
|
||||
|
||||
#else
|
||||
#if defined(SOCK_CLOEXEC)
|
||||
nwio->handle = socket (family, type | SOCK_CLOEXEC, 0);
|
||||
#else
|
||||
nwio->handle = socket (family, type, 0);
|
||||
#endif
|
||||
if (nwio->handle <= -1)
|
||||
{
|
||||
nwio->errnum = syserr_to_errnum (errno);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
#if defined(FD_CLOEXEC)
|
||||
#if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC)
|
||||
{
|
||||
int tmp = fcntl (nwio->handle, F_GETFD);
|
||||
if (tmp >= 0) fcntl (nwio->handle, F_SETFD, tmp | FD_CLOEXEC);
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
QSE_IMPLEMENT_COMMON_FUNCTIONS (upxd)
|
||||
|
||||
static void disable_all_servers (qse_upxd_t* upxd);
|
||||
static void free_all_servers (qse_upxd_t* upxd);
|
||||
static qse_upxd_server_session_t* find_server_session (
|
||||
qse_upxd_t* upxd, qse_upxd_server_t* server, qse_nwad_t* from);
|
||||
@ -63,8 +64,14 @@ int qse_upxd_init (qse_upxd_t* upxd, qse_mmgr_t* mmgr)
|
||||
|
||||
void qse_upxd_fini (qse_upxd_t* upxd)
|
||||
{
|
||||
QSE_ASSERTX (upxd->server.nactive == 0,
|
||||
"Deactivate all servers before destroying me");
|
||||
if (upxd->server.nactive > 0) disable_all_servers (upxd);
|
||||
|
||||
if (upxd->mux)
|
||||
{
|
||||
upxd->cbs->mux.close (upxd, upxd->mux);
|
||||
upxd->mux = QSE_NULL;
|
||||
}
|
||||
|
||||
free_all_servers (upxd);
|
||||
}
|
||||
|
||||
@ -98,10 +105,6 @@ QSE_INLINE void qse_upxd_freemem (qse_upxd_t* upxd, void* ptr)
|
||||
QSE_MMGR_FREE (upxd->mmgr, ptr);
|
||||
}
|
||||
|
||||
void qse_upxd_stop (qse_upxd_t* upxd)
|
||||
{
|
||||
upxd->stopreq = 1;
|
||||
}
|
||||
|
||||
static int perform_session_task (
|
||||
qse_upxd_t* upxd, void* mux, qse_ubi_t handle, void* cbarg)
|
||||
@ -203,7 +206,6 @@ static qse_upxd_server_session_t* find_server_session (
|
||||
|
||||
QSE_MEMSET (session, 0, QSE_SIZEOF(*session));
|
||||
|
||||
|
||||
if (qse_gettime (&session->created) <= -1)
|
||||
{
|
||||
qse_upxd_freemem (upxd, session);
|
||||
@ -275,10 +277,10 @@ static void release_session (
|
||||
qse_upxd_freemem (upxd, session);
|
||||
}
|
||||
|
||||
static int activate_server (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
static int enable_server (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
{
|
||||
QSE_ASSERT (upxd->cbs != QSE_NULL);
|
||||
QSE_ASSERT (!(server->flags & QSE_UPXD_SERVER_ACTIVE));
|
||||
QSE_ASSERT (!(server->flags & QSE_UPXD_SERVER_ENABLED));
|
||||
|
||||
if (upxd->cbs->sock.open (upxd, &server->local) <= -1)
|
||||
{
|
||||
@ -293,17 +295,17 @@ static int activate_server (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
return -1;
|
||||
}
|
||||
|
||||
server->flags |= QSE_UPXD_SERVER_ACTIVE;
|
||||
server->flags |= QSE_UPXD_SERVER_ENABLED;
|
||||
upxd->server.nactive++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deactivate_server (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
static void disable_server (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
{
|
||||
qse_upxd_server_session_t* session;
|
||||
|
||||
QSE_ASSERT (upxd->cbs != QSE_NULL);
|
||||
QSE_ASSERT (server->flags & QSE_UPXD_SERVER_ACTIVE);
|
||||
QSE_ASSERT (server->flags & QSE_UPXD_SERVER_ENABLED);
|
||||
|
||||
session = server->session.list;
|
||||
while (session)
|
||||
@ -316,32 +318,32 @@ static void deactivate_server (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
upxd->cbs->mux.delhnd (upxd, upxd->mux, server->local.handle);
|
||||
upxd->cbs->sock.close (upxd, &server->local);
|
||||
|
||||
server->flags &= ~QSE_UPXD_SERVER_ACTIVE;
|
||||
server->flags &= ~QSE_UPXD_SERVER_ENABLED;
|
||||
upxd->server.nactive--;
|
||||
}
|
||||
|
||||
static void activate_all_servers (qse_upxd_t* upxd)
|
||||
static void enable_all_servers (qse_upxd_t* upxd)
|
||||
{
|
||||
qse_upxd_server_t* server;
|
||||
|
||||
for (server = upxd->server.list; server; server = server->next)
|
||||
{
|
||||
if (!(server->flags & QSE_UPXD_SERVER_ACTIVE))
|
||||
if (!(server->flags & QSE_UPXD_SERVER_ENABLED))
|
||||
{
|
||||
activate_server (upxd, server);
|
||||
enable_server (upxd, server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void deactivate_all_servers (qse_upxd_t* upxd)
|
||||
static void disable_all_servers (qse_upxd_t* upxd)
|
||||
{
|
||||
qse_upxd_server_t* server;
|
||||
|
||||
server = upxd->server.list;
|
||||
while (server)
|
||||
{
|
||||
if (server->flags & QSE_UPXD_SERVER_ACTIVE)
|
||||
deactivate_server (upxd, server);
|
||||
if (server->flags & QSE_UPXD_SERVER_ENABLED)
|
||||
disable_server (upxd, server);
|
||||
|
||||
server = server->next;
|
||||
}
|
||||
@ -362,29 +364,6 @@ static void free_all_servers (qse_upxd_t* upxd)
|
||||
upxd->server.list = QSE_NULL;
|
||||
}
|
||||
|
||||
static void purge_deleted_servers (qse_upxd_t* upxd)
|
||||
{
|
||||
qse_upxd_server_t* server;
|
||||
qse_upxd_server_t* next;
|
||||
|
||||
server = upxd->server.list;
|
||||
while (server)
|
||||
{
|
||||
next = server->next;
|
||||
|
||||
if (server->flags & QSE_UPXD_SERVER_DELETED)
|
||||
{
|
||||
if (server->flags & QSE_UPXD_SERVER_ACTIVE)
|
||||
deactivate_server (upxd, server);
|
||||
|
||||
if (server == upxd->server.list) upxd->server.list = next;
|
||||
|
||||
QSE_MMGR_FREE (upxd->mmgr, server);
|
||||
}
|
||||
server = next;
|
||||
}
|
||||
}
|
||||
|
||||
qse_upxd_server_t* qse_upxd_addserver (
|
||||
qse_upxd_t* upxd, const qse_nwad_t* nwad, const qse_char_t* dev)
|
||||
{
|
||||
@ -411,10 +390,11 @@ qse_upxd_server_t* qse_upxd_addserver (
|
||||
}
|
||||
server->local.bind = *nwad;
|
||||
|
||||
upxd->cbs->lock.acquire (upxd);
|
||||
/* chain it to the head of the list */
|
||||
if (upxd->server.list)
|
||||
upxd->server.list->prev = server;
|
||||
server->next = upxd->server.list;
|
||||
upxd->server.list = server;
|
||||
upxd->cbs->lock.release (upxd);
|
||||
|
||||
return server;
|
||||
}
|
||||
@ -422,7 +402,13 @@ qse_upxd_server_t* qse_upxd_addserver (
|
||||
void qse_upxd_delserver (
|
||||
qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
{
|
||||
server->flags |= QSE_UPXD_SERVER_DELETED;
|
||||
if (server->flags & QSE_UPXD_SERVER_ENABLED)
|
||||
disable_server (upxd, server);
|
||||
|
||||
/* unchain the session from the list */
|
||||
if (server->next) server->next->prev = server->prev;
|
||||
if (server->prev) server->prev->next = server->next;
|
||||
else upxd->server.list = server->next;
|
||||
}
|
||||
|
||||
void* qse_upxd_getserverctx (
|
||||
@ -478,7 +464,7 @@ static void purge_idle_sessions (qse_upxd_t* upxd)
|
||||
|
||||
for (server = upxd->server.list; server; server = server->next)
|
||||
{
|
||||
if (server->flags & QSE_UPXD_SERVER_ACTIVE)
|
||||
if (server->flags & QSE_UPXD_SERVER_ENABLED)
|
||||
{
|
||||
purge_idle_sessions_in_server (upxd, server);
|
||||
}
|
||||
@ -491,27 +477,26 @@ int qse_upxd_loop (qse_upxd_t* upxd, qse_ntime_t timeout)
|
||||
|
||||
QSE_ASSERTX (upxd->cbs != QSE_NULL,
|
||||
"Call qse_upxd_setcbs() before calling qse_upxd_loop()");
|
||||
QSE_ASSERT (upxd->mux == QSE_NULL);
|
||||
|
||||
if (upxd->cbs == QSE_NULL || upxd->mux /*||
|
||||
upxd->server.list == QSE_NULL*/)
|
||||
if (upxd->cbs == QSE_NULL)
|
||||
{
|
||||
upxd->errnum = QSE_UPXD_EINVAL;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (upxd->mux)
|
||||
{
|
||||
/* close the mutiplexer if it's open */
|
||||
upxd->cbs->mux.close (upxd, upxd->mux);
|
||||
upxd->mux = QSE_NULL;
|
||||
}
|
||||
|
||||
upxd->stopreq = 0;
|
||||
upxd->mux = upxd->cbs-> mux.open (upxd);
|
||||
if (upxd->mux == QSE_NULL) goto oops;
|
||||
|
||||
activate_all_servers (upxd);
|
||||
if (upxd->server.nactive == 0)
|
||||
{
|
||||
/* at least 1 server must be activated here */
|
||||
upxd->errnum = QSE_UPXD_EINVAL;
|
||||
goto oops;
|
||||
}
|
||||
|
||||
enable_all_servers (upxd);
|
||||
|
||||
while (!upxd->stopreq)
|
||||
{
|
||||
int count;
|
||||
@ -521,18 +506,66 @@ int qse_upxd_loop (qse_upxd_t* upxd, qse_ntime_t timeout)
|
||||
{
|
||||
/* TODO: anything? */
|
||||
}
|
||||
|
||||
upxd->cbs->lock.acquire (upxd);
|
||||
|
||||
purge_idle_sessions (upxd);
|
||||
purge_deleted_servers (upxd);
|
||||
activate_all_servers (upxd);
|
||||
upxd->cbs->lock.release (upxd);
|
||||
enable_all_servers (upxd);
|
||||
}
|
||||
|
||||
retv = 0;
|
||||
|
||||
oops:
|
||||
if (upxd->server.nactive > 0) deactivate_all_servers (upxd);
|
||||
if (upxd->mux) upxd->cbs->mux.close (upxd, upxd->mux);
|
||||
if (upxd->server.nactive > 0) disable_all_servers (upxd);
|
||||
if (upxd->mux)
|
||||
{
|
||||
upxd->cbs->mux.close (upxd, upxd->mux);
|
||||
upxd->mux = QSE_NULL;
|
||||
}
|
||||
return retv;
|
||||
}
|
||||
|
||||
void qse_upxd_stop (qse_upxd_t* upxd)
|
||||
{
|
||||
upxd->stopreq = 1;
|
||||
}
|
||||
|
||||
int qse_upxd_enableserver (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
{
|
||||
if (server->flags & QSE_UPXD_SERVER_ENABLED)
|
||||
{
|
||||
upxd->errnum = QSE_UPXD_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return enable_server (upxd, server);
|
||||
}
|
||||
|
||||
int qse_upxd_disableserver (qse_upxd_t* upxd, qse_upxd_server_t* server)
|
||||
{
|
||||
if (!(server->flags & QSE_UPXD_SERVER_ENABLED))
|
||||
{
|
||||
upxd->errnum = QSE_UPXD_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
disable_server (upxd, server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qse_upxd_poll (qse_upxd_t* upxd, qse_ntime_t timeout)
|
||||
{
|
||||
int ret;
|
||||
|
||||
QSE_ASSERTX (upxd->cbs != QSE_NULL,
|
||||
"Call qse_upxd_setcbs() before calling qse_upxd_loop()");
|
||||
|
||||
if (upxd->mux == QSE_NULL)
|
||||
{
|
||||
upxd->mux = upxd->cbs-> mux.open (upxd);
|
||||
if (upxd->mux == QSE_NULL) return -1;
|
||||
}
|
||||
|
||||
ret = upxd->cbs->mux.poll (upxd, upxd->mux, timeout);
|
||||
purge_idle_sessions (upxd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ typedef struct qse_upxd_server_session_t qse_upxd_server_session_t;
|
||||
struct qse_upxd_server_t
|
||||
{
|
||||
qse_upxd_server_t* next;
|
||||
qse_upxd_server_t* prev;
|
||||
|
||||
#define QSE_UPXD_SERVER_ACTIVE (1 << 0)
|
||||
#define QSE_UPXD_SERVER_DELETED (1 << 1)
|
||||
#define QSE_UPXD_SERVER_ENABLED (1 << 0)
|
||||
int flags;
|
||||
|
||||
/* the socket can be bound to this interface.
|
||||
|
Reference in New Issue
Block a user