mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
1798 lines
50 KiB
C
1798 lines
50 KiB
C
// wi_auth_declaration2.h
|
||
|
||
#ifndef U_WI_AUTH_DECLARATION2_H
|
||
#define U_WI_AUTH_DECLARATION2_H 1
|
||
|
||
static UString* ip;
|
||
static UString* mac;
|
||
|
||
static UString* ap;
|
||
static UString* ap_label;
|
||
static UString* ap_address;
|
||
static UString* ap_hostname;
|
||
static UString* nodog_conf;
|
||
static UString* key_session;
|
||
static UString* db_anagrafica;
|
||
static UString* allowed_web_hosts;
|
||
|
||
static UFile* file_LOG;
|
||
static UFile* file_WARNING;
|
||
|
||
static UVector<UString>* vmac;
|
||
static UVector<UString>* vapID;
|
||
static UVector<UString>* vwelcome_file;
|
||
|
||
static UREDISClient_Base* rc;
|
||
static UHttpClient<UTCPSocket>* client;
|
||
|
||
static UHTTP::UFileCacheData* deny_html;
|
||
|
||
static void* peer;
|
||
static UPing* sockp;
|
||
static bool ap_consume;
|
||
static UString* policySessionId;
|
||
static uint8_t vwelcome_index[2][3]; // policy: (DAILY|FLAT), SessionNotify: (0,notify) (1,no_notify) (2,strict_notify)
|
||
static int facceptTermsOfConditionsRenew;
|
||
static uint64_t counter, device_counter, max_traffic_daily;
|
||
static uint8_t policySessionNotify, policySessionNotifyDefault;
|
||
static uint32_t addr, old_addr, ip_peer, created, lastUpdate, lastReset, idx, duration_privacy_policy, vec_logout[8192];
|
||
|
||
#define U_CLEAN_INTERVAL (60U * 60U) // 1h
|
||
#define U_MAX_TIME_NO_TRAFFIC (15U * 60U) // 15m
|
||
|
||
#define U_LOGGER(fmt,args...) ULog::log(file_WARNING->getFd(), U_CONSTANT_TO_PARAM("%v: " fmt), UClientImage_Base::request_uri->rep , ##args)
|
||
|
||
/**
|
||
enum UPolicy {
|
||
U_NOTIFY = 0x00,
|
||
U_NO_NOTIFY = 0x01,
|
||
U_STRICT_NOTIFY = 0x02,
|
||
U_HINERIT = 0x03
|
||
};
|
||
*/
|
||
|
||
static void loadAnagrafica()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::loadAnagrafica()")
|
||
|
||
U_INTERNAL_ASSERT_POINTER(db_anagrafica)
|
||
|
||
if (*db_anagrafica) db_anagrafica->clear();
|
||
|
||
*db_anagrafica = UFile::contentOf(U_STRING_FROM_CONSTANT("../anagrafica.txt"));
|
||
|
||
if (db_anagrafica->empty())
|
||
{
|
||
U_ERROR("../anagrafica.txt empty");
|
||
}
|
||
|
||
UVector<UString> vnetmask;
|
||
UTokenizer tok(*db_anagrafica, ",\n");
|
||
UString buffer(U_CAPACITY), lip, lnetmask, lbl, lnetmask1, lbl1, name;
|
||
|
||
/**
|
||
* 10.8.0.13,172.17.13.0/24,368
|
||
* 10.8.0.13,172.16.13.0/24,368
|
||
* 10.8.0.255,172.16.255.0/24,51
|
||
* 151.11.47.3,172.23.0.0/20,47,pippo
|
||
* 151.11.47.3,172.23.0.0/20,213,pluto
|
||
* 192.168.44.55,172.16.55.0/24,55
|
||
* 192.168.44.55,172.16.65.0/24,65
|
||
*/
|
||
|
||
(void) tok.next(lip, (bool*)U_NULLPTR);
|
||
|
||
U_INTERNAL_ASSERT(lip)
|
||
|
||
loop:
|
||
(void) tok.next(lnetmask, (bool*)U_NULLPTR);
|
||
(void) tok.next(lbl, (bool*)U_NULLPTR);
|
||
|
||
U_INTERNAL_ASSERT(lbl)
|
||
U_INTERNAL_ASSERT(lnetmask)
|
||
U_ASSERT(vnetmask.empty())
|
||
|
||
U_INTERNAL_DUMP("tok.previous() = %C tok.current() = %C", tok.previous(), tok.current())
|
||
|
||
if (tok.previous() != ',') name.clear();
|
||
else (void) tok.next(name, (bool*)U_NULLPTR);
|
||
|
||
vnetmask.push_back(lnetmask);
|
||
|
||
U_INTERNAL_DUMP("lip = %V lbl = %V lnetmask = %V name = %V", lip.rep, lbl.rep, lnetmask.rep, name.rep)
|
||
|
||
*ip = lip;
|
||
|
||
(void) UIPAddress::getBinaryForm(ip->c_str(), addr, true);
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u ip %v"), addr, ip->rep);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("CAPTIVE:byId 0 id:%u"), addr);
|
||
|
||
buffer.snprintf(U_CONSTANT_TO_PARAM("AP:id:%v captiveId %u network %v"), lbl.rep, addr, lnetmask.rep);
|
||
|
||
if (name) buffer.snprintf_add(U_CONSTANT_TO_PARAM(" name %V"), name.rep);
|
||
|
||
(void) rc->hmset(buffer);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("AP:byCaptiveId %u id:%v;network:%v"), addr, lbl.rep, lnetmask.rep);
|
||
|
||
while (tok.next(lip, (bool*)U_NULLPTR))
|
||
{
|
||
if (ip->equal(lip) == false)
|
||
{
|
||
if (vnetmask.size() > 1)
|
||
{
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("AP:id:%v network %v"), lbl.rep, vnetmask.join(0, U_CONSTANT_TO_PARAM(",")).rep);
|
||
}
|
||
|
||
vnetmask.clear();
|
||
|
||
goto loop;
|
||
}
|
||
|
||
(void) tok.next(lnetmask1, (bool*)U_NULLPTR);
|
||
(void) tok.next(lbl1, (bool*)U_NULLPTR);
|
||
|
||
U_INTERNAL_ASSERT(lbl1)
|
||
U_INTERNAL_ASSERT(lnetmask1)
|
||
|
||
U_INTERNAL_DUMP("tok.current() = %C", tok.current())
|
||
|
||
if (u__isdigit(tok.current())) name.clear();
|
||
else (void) tok.next(name, (bool*)U_NULLPTR);
|
||
|
||
if (lbl1 == lbl)
|
||
{
|
||
U_ASSERT_DIFFERS(lnetmask1, lnetmask)
|
||
|
||
vnetmask.push_back(lnetmask1);
|
||
|
||
if (name) rc->hmset(U_CONSTANT_TO_PARAM("AP:id:%v name %V"), lbl1.rep, name.rep);
|
||
|
||
continue;
|
||
}
|
||
|
||
buffer.snprintf(U_CONSTANT_TO_PARAM("AP:id:%v captiveId %u network %v"), lbl1.rep, addr, lnetmask1.rep);
|
||
|
||
if (name) buffer.snprintf_add(U_CONSTANT_TO_PARAM(" name %V"), name.rep);
|
||
|
||
(void) rc->hmset(buffer);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("AP:byCaptiveId %u id:%v;network:%v"), addr, lbl1.rep, lnetmask1.rep);
|
||
|
||
vnetmask.clear();
|
||
|
||
lbl = lbl1;
|
||
lnetmask = lnetmask1;
|
||
}
|
||
}
|
||
|
||
static void usp_config_wi_auth2()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::usp_config_wi_auth2()")
|
||
|
||
U_INTERNAL_ASSERT_POINTER(UServer_Base::pcfg)
|
||
|
||
// --------------------------------------------------------------------------------------------------------------------------------------
|
||
// configuration parameters
|
||
// --------------------------------------------------------------------------------------------------------------------------------------
|
||
// WELCOME_FILE vector of html files
|
||
// WELCOME_INDEX vector of index for html files - policy: (DAILY|FLAT), SessionNotify: (0,notify) (1,no_notify) (2,strict_notify)
|
||
//
|
||
// MAX_TRAFFIC_DAILY
|
||
// DURATION_PRIVACY_POLICY numbers of days for expiration privacy policy
|
||
// POLICY_SESSION_NOTIFY_DEFAULT (0,notify) (1,no_notify) (2,strict_notify)
|
||
// --------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
UString x = UServer_Base::pcfg->at(U_CONSTANT_TO_PARAM("WELCOME_FILE"));
|
||
|
||
if (x)
|
||
{
|
||
UVector<UString> vec(x);
|
||
uint32_t n = vec.size();
|
||
|
||
if (n < 1 ||
|
||
n > 6)
|
||
{
|
||
U_ERROR("usp_config_wi_auth2(): vector WELCOME_FILE malformed: %V", x.rep);
|
||
}
|
||
|
||
U_INTERNAL_ASSERT_EQUALS(vwelcome_file, U_NULLPTR)
|
||
|
||
U_NEW(UVector<UString>, vwelcome_file, UVector<UString>(vec, n));
|
||
}
|
||
|
||
// policy: (DAILY|FLAT), SessionNotify: (0,notify) (1,no_notify) (2,strict_notify)
|
||
|
||
x = UServer_Base::pcfg->at(U_CONSTANT_TO_PARAM("WELCOME_INDEX"));
|
||
|
||
if (x)
|
||
{
|
||
const char* ptr1 = x.data();
|
||
uint8_t* ptr2 = (uint8_t*)vwelcome_index;
|
||
|
||
for (uint32_t i = 0, n = x.size(); i < n; ++i) ptr2[i] = ptr1[i] - '0';
|
||
}
|
||
|
||
max_traffic_daily = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("MAX_TRAFFIC_DAILY"), 500ULL * 1024ULL * 1024ULL); // 500M
|
||
duration_privacy_policy = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("DURATION_PRIVACY_POLICY"), 365L) * U_ONE_DAY_IN_SECOND; // 1 year
|
||
policySessionNotifyDefault = UServer_Base::pcfg->readLong(U_CONSTANT_TO_PARAM("POLICY_SESSION_NOTIFY_DEFAULT"));
|
||
}
|
||
|
||
static void usp_init_wi_auth2()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::usp_init_wi_auth2()")
|
||
|
||
deny_html = UHTTP::getFileCachePointer(U_CONSTANT_TO_PARAM("deny.html"));
|
||
|
||
if (deny_html == U_NULLPTR)
|
||
{
|
||
U_ERROR("usp_init_wi_auth2(): missing deny.html from cache");
|
||
}
|
||
|
||
if (vwelcome_file == U_NULLPTR)
|
||
{
|
||
U_ERROR("usp_init_wi_auth2(): WELCOME_FILE empty");
|
||
}
|
||
|
||
UString x;
|
||
UHTTP::UFileCacheData* welcome_html;
|
||
|
||
for (uint32_t i = 0, n = vwelcome_file->size(); i < n; ++i)
|
||
{
|
||
x = vwelcome_file->at(i);
|
||
|
||
welcome_html = UHTTP::getFileCachePointer(U_STRING_TO_PARAM(x));
|
||
|
||
if (welcome_html == U_NULLPTR)
|
||
{
|
||
U_ERROR("usp_init_wi_auth2(): missing %V from cache", x.rep);
|
||
}
|
||
}
|
||
|
||
// NODOG config template
|
||
|
||
U_NEW_STRING(nodog_conf, UString(UFile::contentOf(U_STRING_FROM_CONSTANT("../ap/nodog.conf.template"))));
|
||
|
||
if (nodog_conf->empty())
|
||
{
|
||
U_ERROR("usp_init_wi_auth2(): ../ap/nodog.conf.template empty");
|
||
}
|
||
|
||
UString content = UFile::contentOf(U_STRING_FROM_CONSTANT("../DES3_KEY.txt"));
|
||
|
||
if (content.empty())
|
||
{
|
||
U_ERROR("usp_init_wi_auth2(): ../DES3_KEY.txt empty");
|
||
}
|
||
|
||
UDES3::setPassword(content.c_strndup());
|
||
|
||
U_NEW_STRING(db_anagrafica, UString);
|
||
U_NEW_STRING(allowed_web_hosts, UString);
|
||
|
||
content = UFile::contentOf(U_STRING_FROM_CONSTANT("../etc/AllowedWebHosts.txt"));
|
||
|
||
if (content)
|
||
{
|
||
UVector<UString> vec(content);
|
||
|
||
if (vec.empty() == false) *allowed_web_hosts = vec.join() + ' ';
|
||
}
|
||
|
||
U_NEW_STRING(ip, UString);
|
||
U_NEW_STRING(mac, UString);
|
||
|
||
U_NEW_STRING(ap, UString);
|
||
U_NEW_STRING(ap_label, UString);
|
||
U_NEW_STRING(ap_address, UString);
|
||
U_NEW_STRING(ap_hostname, UString);
|
||
U_NEW_STRING(key_session, UString);
|
||
U_NEW_STRING(policySessionId, UString);
|
||
|
||
U_NEW(UVector<UString>, vmac, UVector<UString>);
|
||
U_NEW(UVector<UString>, vapID, UVector<UString>);
|
||
|
||
U_NEW(UFile, file_LOG, UFile(U_STRING_FROM_CONSTANT("../log/wifi-log")));
|
||
U_NEW(UFile, file_WARNING, UFile(U_STRING_FROM_CONSTANT("../log/wifi-warning")));
|
||
|
||
UServer_Base::update_date =
|
||
UServer_Base::update_date1 = true;
|
||
|
||
(void) UServer_Base::addLog(file_LOG);
|
||
(void) UServer_Base::addLog(file_WARNING);
|
||
|
||
// HTTP client
|
||
|
||
U_NEW(UHttpClient<UTCPSocket>, client, UHttpClient<UTCPSocket>(U_NULLPTR));
|
||
|
||
client->setFollowRedirects(true, false);
|
||
client->getResponseHeader()->setIgnoreCase(false);
|
||
|
||
U_ASSERT_EQUALS(client->isPasswordAuthentication(), false)
|
||
|
||
// CLEAN MONITORING
|
||
|
||
U_NEW(UPing, sockp, UPing(5000, UClientImage_Base::bIPv6));
|
||
|
||
if (sockp->initPing() == false)
|
||
{
|
||
U_DELETE(sockp)
|
||
|
||
sockp = U_NULLPTR;
|
||
}
|
||
|
||
// REDIS client
|
||
|
||
U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
|
||
|
||
if (rc->connect() == false)
|
||
{
|
||
U_ERROR("usp_init_wi_auth2(): %V", rc->UClient_Base::getResponse().rep);
|
||
}
|
||
|
||
// ANAGRAFICA
|
||
|
||
loadAnagrafica();
|
||
}
|
||
|
||
static void usp_fork_wi_auth2()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::usp_fork_wi_auth2()")
|
||
|
||
// REDIS client
|
||
|
||
U_INTERNAL_ASSERT_POINTER(rc)
|
||
|
||
if (rc->UClient_Base::reConnect() == false)
|
||
{
|
||
U_ERROR("usp_fork_wi_auth2(): %V", rc->UClient_Base::getResponse().rep);
|
||
}
|
||
}
|
||
|
||
static void usp_end_wi_auth2()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::usp_end_wi_auth2()")
|
||
|
||
#ifdef DEBUG
|
||
U_DELETE(ip)
|
||
U_DELETE(mac)
|
||
|
||
U_DELETE(ap)
|
||
U_DELETE(ap_label)
|
||
U_DELETE(ap_address)
|
||
U_DELETE(ap_hostname)
|
||
U_DELETE(nodog_conf)
|
||
U_DELETE(key_session)
|
||
U_DELETE(policySessionId)
|
||
U_DELETE(allowed_web_hosts)
|
||
|
||
U_DELETE(vmac);
|
||
U_DELETE(vapID);
|
||
|
||
U_DELETE(db_anagrafica)
|
||
|
||
U_DELETE(rc)
|
||
U_DELETE(client)
|
||
|
||
if (sockp) U_DELETE(sockp)
|
||
if (vwelcome_file) U_DELETE(vwelcome_file)
|
||
#endif
|
||
}
|
||
|
||
static bool setLabelAndNetmaskFromAnagrafica(UString& label, UString& netmask)
|
||
{
|
||
U_TRACE(5, "::setLabelAndNetmaskFromAnagrafica(%p,%p,%p)", &label, &netmask)
|
||
|
||
U_INTERNAL_DUMP("ap_address = %V", ap_address)
|
||
|
||
U_INTERNAL_ASSERT(*ap_address)
|
||
|
||
uint32_t pos = 0;
|
||
|
||
/**
|
||
* 159.213.248.233,172.25.0.0/22,213
|
||
*/
|
||
|
||
loop:
|
||
pos = db_anagrafica->find(*ap_address, pos);
|
||
|
||
U_INTERNAL_DUMP("pos = %u", pos)
|
||
|
||
if (pos == U_NOT_FOUND) U_RETURN(false);
|
||
|
||
pos += ap_address->size();
|
||
|
||
if (db_anagrafica->c_char(pos) != ',') goto loop;
|
||
|
||
if (pos != U_NOT_FOUND)
|
||
{
|
||
UVector<UString> vlabel, vnetmask;
|
||
UString lip, lnetmask, lbl, lnetmask1, lbl1;
|
||
UTokenizer tok(db_anagrafica->substr(pos), ",\n");
|
||
|
||
/**
|
||
* 159.213.248.233,172.25.0.0/22,213
|
||
*/
|
||
|
||
(void) tok.next(lnetmask, (bool*)U_NULLPTR);
|
||
(void) tok.next(lbl, (bool*)U_NULLPTR);
|
||
|
||
U_INTERNAL_ASSERT(lbl)
|
||
U_INTERNAL_ASSERT(lnetmask)
|
||
|
||
vlabel.push_back(lbl);
|
||
vnetmask.push_back(lnetmask);
|
||
|
||
U_INTERNAL_DUMP("tok.current() = %C", tok.current())
|
||
|
||
if (u__isdigit(tok.current()) == false) (void) tok.skipToken();
|
||
|
||
/**
|
||
* 151.11.47.3,172.23.0.0/20,47
|
||
* 151.11.47.3,172.23.0.0/20,215
|
||
* 151.11.47.3,172.23.0.0/20,216
|
||
*/
|
||
|
||
while (tok.next(lip, (bool*)U_NULLPTR) &&
|
||
ap_address->equal(lip))
|
||
{
|
||
(void) tok.next(lnetmask1, (bool*)U_NULLPTR);
|
||
(void) tok.next(lbl1, (bool*)U_NULLPTR);
|
||
|
||
U_INTERNAL_ASSERT(lbl1)
|
||
U_INTERNAL_ASSERT(lnetmask1)
|
||
|
||
U_INTERNAL_DUMP("tok.current() = %C", tok.current())
|
||
|
||
if (u__isdigit(tok.current()) == false) (void) tok.skipToken();
|
||
|
||
vlabel.push_back(lbl1);
|
||
if (lnetmask != lnetmask1) vnetmask.push_back(lnetmask1);
|
||
}
|
||
|
||
/**
|
||
* 10.8.0.13,172.17.13.0/24,368
|
||
* 10.8.0.13,172.16.13.0/24,368
|
||
*/
|
||
|
||
U_DUMP("vlabel.size() = %u vnetmask.size() = %u", vlabel.size(), vnetmask.size())
|
||
|
||
if (vlabel.size() == vnetmask.size())
|
||
{
|
||
label = vlabel.join();
|
||
netmask = vnetmask.join();
|
||
}
|
||
else
|
||
{
|
||
U_ASSERT_EQUALS(vnetmask.size(), 1)
|
||
|
||
label = vlabel[0];
|
||
netmask = vnetmask[0];
|
||
}
|
||
|
||
U_RETURN(true);
|
||
}
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
static void resetAccessPoint()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::resetAccessPoint()")
|
||
|
||
ap_label->clear();
|
||
ap_address->clear();
|
||
ap_hostname->clear();
|
||
}
|
||
|
||
static bool setAccessPoint()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::setAccessPoint()")
|
||
|
||
resetAccessPoint();
|
||
|
||
if (ap->empty())
|
||
{
|
||
U_LOGGER("*** AP STRING EMPTY ***", 0);
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
uint32_t pos1 = ap->find('@');
|
||
|
||
if (pos1 == U_NOT_FOUND) U_RETURN(false);
|
||
|
||
*ap_label = ap->substr(0U, pos1).copy();
|
||
|
||
uint32_t pos2 = ap->find('/', pos1+1);
|
||
|
||
if (pos2 == U_NOT_FOUND) *ap_hostname = ap->substr(pos1+1).copy();
|
||
else
|
||
{
|
||
*ap_address = ap->substr(pos1+1, pos2-pos1-1).copy();
|
||
|
||
if (*ap_address &&
|
||
UIPAddress::getBinaryForm(ap_address->c_str(), addr, true) == false)
|
||
{
|
||
U_LOGGER("*** AP ADDRESS(%v) NOT VALID ***", ap_address->rep);
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
*ap_hostname = ap->substr(pos2+1).copy();
|
||
}
|
||
|
||
if (u_isHostName(U_STRING_TO_PARAM(*ap_hostname)) == false)
|
||
{
|
||
U_LOGGER("*** AP HOSTNAME(%v) NOT VALID ***", ap_hostname->rep);
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
U_INTERNAL_DUMP("ap_address = %V ap_hostname = %V ap_label = %V", ap_address->rep, ap_hostname->rep, ap_label->rep)
|
||
|
||
U_RETURN(true);
|
||
}
|
||
|
||
static inline void setSessionKey(const UString& lmac, const UString& label)
|
||
{
|
||
U_TRACE(5, "::setSessionKey(%V,%V)", lmac.rep, label.rep)
|
||
|
||
U_ASSERT(lmac.isXMacAddr())
|
||
|
||
key_session->setBuffer(200U); key_session->snprintf(U_CONSTANT_TO_PARAM("captiveId:%u;apId:%v;deviceId:%v;ip:%v"), addr, label.rep, lmac.rep, ip->rep);
|
||
}
|
||
|
||
static void setSessionPolicy()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::setSessionPolicy()")
|
||
|
||
U_INTERNAL_DUMP("ap_label = %V mac = %V", ap_label->rep, mac->rep)
|
||
|
||
(void) rc->hmget(U_CONSTANT_TO_PARAM("DEVICE:id:%v pId pNotify"), mac->rep);
|
||
|
||
if ((*policySessionId = rc->getString())) rc->setUInt8(policySessionNotify, 1);
|
||
else
|
||
{
|
||
// da configurazione
|
||
|
||
*policySessionId = U_STRING_FROM_CONSTANT("DAILY");
|
||
|
||
policySessionNotify = policySessionNotifyDefault;
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("DEVICE:id:%v id %v pId DAILY pNotify %u pCounter 0 lastAccess %u pLastReset %u created %u"),
|
||
mac->rep, mac->rep, policySessionNotifyDefault, u_now->tv_sec, u_now->tv_sec, u_now->tv_sec);
|
||
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("DEVICE:bylastAccess %u id:%v"), u_now->tv_sec, mac->rep);
|
||
}
|
||
|
||
U_INTERNAL_DUMP("policySessionId = %V policySessionNotify = %u", policySessionId->rep, policySessionNotify)
|
||
|
||
U_INTERNAL_ASSERT(*policySessionId)
|
||
|
||
// reset fields SESSION
|
||
|
||
counter = 0;
|
||
created =
|
||
lastUpdate = u_now->tv_sec;
|
||
|
||
(void) rc->hmget(U_CONSTANT_TO_PARAM("AP:id:%v consume notify"), ap_label->rep);
|
||
|
||
uint8_t ap_notify;
|
||
|
||
if (rc->getResult())
|
||
{
|
||
ap_consume = rc->x.strtob();
|
||
|
||
rc->setUInt8(ap_notify, 1);
|
||
}
|
||
else
|
||
{
|
||
ap_consume = true;
|
||
ap_notify = 0; // notify
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("AP:id:%v consume 1 notify 3"), ap_label->rep);
|
||
}
|
||
|
||
U_INTERNAL_DUMP("ap_consume = %b ap_notify = %u", ap_consume, ap_notify)
|
||
|
||
switch (ap_notify)
|
||
{
|
||
case 0: policySessionNotify = 0; break; // (notify)
|
||
case 1: policySessionNotify = 1; break; // (no notify)
|
||
case 2: policySessionNotify = 2; break; // (strict notify)
|
||
// case 3: break; // (hinerit)
|
||
}
|
||
|
||
U_INTERNAL_DUMP("policySessionNotify = %u", policySessionNotify)
|
||
}
|
||
|
||
static bool getSession(const char* op, uint32_t op_len)
|
||
{
|
||
U_TRACE(5, "::getSession(%.*S,%u)", op_len, op, op_len)
|
||
|
||
(void) rc->hmget(U_CONSTANT_TO_PARAM("SESSION:%v created pId notify consume counter lastUpdate captiveId apId deviceId ip"), key_session->rep);
|
||
|
||
if (rc->getResult())
|
||
{
|
||
created = rc->x.strtoul();
|
||
*policySessionId = rc->getString(1);
|
||
|
||
rc->setUInt8(policySessionNotify, 2);
|
||
|
||
ap_consume = rc->getBool(3);
|
||
counter = rc->getUInt64(4);
|
||
lastUpdate = rc->getULong(5);
|
||
|
||
U_INTERNAL_DUMP("policySessionId = %V ap_consume = %b counter = %llu created = %#2D lastUpdate = %#2D (%u <=> midnigth %u)",
|
||
policySessionId->rep, ap_consume, counter, created, lastUpdate, u_get_localtime(lastUpdate) / U_ONE_DAY_IN_SECOND, u_getLocalTime() / U_ONE_DAY_IN_SECOND)
|
||
|
||
if (policySessionId->empty())
|
||
{
|
||
U_LOGGER("*** SESSION(%V) WITH pId EMPTY ***", key_session->rep);
|
||
|
||
*policySessionId = U_STRING_FROM_CONSTANT("DAILY");
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("SESSION:%v pId DAILY"), key_session->rep);
|
||
}
|
||
|
||
U_RETURN(true);
|
||
}
|
||
|
||
U_LOGGER("*** SESSION(%V) NOT FOUND at %.*s() ***", key_session->rep, op_len, op);
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
static bool getSession(const UString& lmac, const UString& label, const char* op, uint32_t op_len)
|
||
{
|
||
U_TRACE(5, "::getSession((%V,%V,%.*S,%u)", lmac.rep, label.rep, op_len, op, op_len)
|
||
|
||
U_INTERNAL_ASSERT(label)
|
||
|
||
if (u_isXMacAddr(U_STRING_TO_PARAM(lmac)) == false)
|
||
{
|
||
U_LOGGER("*** we have a wrong old MAC(%V) ***", lmac.rep);
|
||
}
|
||
else
|
||
{
|
||
setSessionKey(lmac, label);
|
||
|
||
if (getSession(op, op_len)) U_RETURN(true);
|
||
}
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
static uint32_t getApInfo(const UString& label, char* buffer)
|
||
{
|
||
U_TRACE(5, "::getApInfo(%V,%p)", label.rep, buffer)
|
||
|
||
return u__snprintf(buffer, 1024, U_CONSTANT_TO_PARAM("%v@%v/%v"), label.rep, ap_address->rep, ap_hostname->rep);
|
||
}
|
||
|
||
static void writeToLOG(const UString& label, const char* op, uint32_t op_len, const UString& opt)
|
||
{
|
||
U_TRACE(5, "::writeToLOG(%V,%.*S,%u,%V)", label.rep, op_len, op, op_len, opt.rep)
|
||
|
||
U_INTERNAL_ASSERT_POINTER(op)
|
||
U_INTERNAL_ASSERT_MAJOR(op_len, 0)
|
||
|
||
char buffer[1024];
|
||
|
||
// 11/02/18 04:14:21 op: PERMIT, mac: 20:ee:28:d0:38:93, ip: 172.22.155.28, ap: 61@151.11.47.8/CareggiConc-x86_64, policy: FLAT|no_consume|notify
|
||
// 11/02/18 04:14:21 op: NOTIFIED, mac: 20:ee:28:d0:38:93, ip: 172.22.155.28, ap: 61@151.11.47.8/CareggiConc-x86_64, policy: FLAT|no_consume|notify
|
||
// 11/02/18 04:14:21 op: RST_SESSION, mac: 20:ee:28:d0:38:93, ip: 172.22.155.28, ap: 61@151.11.47.8/CareggiConc-x86_64, policy: DAILY|consume|notify, traffic: 100
|
||
// 11/02/18 04:14:21 op: DENY_NO_TRAFFIC, mac: 20:ee:28:d0:38:93, ip: 172.22.155.28, ap: 61@151.11.47.8/CareggiConc-x86_64, policy: FLAT|consume|notify, traffic: 100, elapsed: 10
|
||
|
||
ULog::log(file_LOG->getFd(),
|
||
U_CONSTANT_TO_PARAM("op: %.*s, mac: %v, ip: %v, ap: %.*s, policy: %v|%.*sconsume|%snotify%v"),
|
||
op_len, op, mac->rep, ip->rep, getApInfo(label, buffer), buffer, policySessionId->rep, (ap_consume ? 0 : 3), "no_", (policySessionNotify == 0 ? "" :
|
||
policySessionNotify == 1 ? "no_" : "strict_"), opt.rep);
|
||
}
|
||
|
||
static void writeSessionToLOG(const UString& label, const char* op, uint32_t op_len)
|
||
{
|
||
U_TRACE(5, "::writeSessionToLOG(%V,%.*S,%u)", label.rep, op_len, op, op_len)
|
||
|
||
UString opt(200U);
|
||
|
||
opt.snprintf(U_CONSTANT_TO_PARAM(", traffic: %llu, elapsed: %u"), counter/1024, (u_now->tv_sec-created)/60);
|
||
|
||
writeToLOG(label, op, op_len, opt);
|
||
}
|
||
|
||
static void deleteSession()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::deleteSession()")
|
||
|
||
(void) rc->del(U_CONSTANT_TO_PARAM("SESSION:%v"), key_session->rep);
|
||
(void) rc->zrem(U_CONSTANT_TO_PARAM("SESSION:byCaptiveIdAndApId deviceId:%v;ip:%v"), mac->rep, ip->rep);
|
||
(void) rc->zrem(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate %v"), key_session->rep);
|
||
|
||
// U_LOGGER("*** SESSION(%V) deleted at deleteSession() ***", key_session->rep);
|
||
}
|
||
|
||
static void resetDeviceDailyCounter()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::resetDeviceDailyCounter()")
|
||
|
||
U_ASSERT(policySessionId->equal(U_CONSTANT_TO_PARAM("DAILY")))
|
||
|
||
(void) rc->hmget(U_CONSTANT_TO_PARAM("DEVICE:id:%v pCounter pLastReset"), mac->rep);
|
||
|
||
device_counter = rc->getUInt64();
|
||
lastReset = rc->getULong(1);
|
||
|
||
if (UTimeDate::compareLocalDay(lastReset) < 0)
|
||
{
|
||
device_counter = 0;
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("DEVICE:id:%v pCounter 0 pLastReset %u"), mac->rep, u_now->tv_sec);
|
||
}
|
||
}
|
||
|
||
static bool checkDevice()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::checkDevice()")
|
||
|
||
if (ap_consume &&
|
||
policySessionId->equal(U_CONSTANT_TO_PARAM("DAILY")))
|
||
{
|
||
resetDeviceDailyCounter();
|
||
|
||
if (device_counter >= max_traffic_daily) U_RETURN(false);
|
||
}
|
||
|
||
U_RETURN(true);
|
||
}
|
||
|
||
static bool sendRequestToNodog(const char* req, uint32_t req_len, const UString& data)
|
||
{
|
||
U_TRACE(5, "::sendRequestToNodog(%.*S,%u,%V)", req_len, req, req_len, data.rep)
|
||
|
||
UString url(100U);
|
||
|
||
url.snprintf(U_CONSTANT_TO_PARAM("http://%v:5280/%.*s"), ap_address->rep, req_len, req);
|
||
|
||
return client->sendPOSTRequestAsync(data, url);
|
||
}
|
||
|
||
static bool getDataFromPOST(bool bpeer)
|
||
{
|
||
U_TRACE(5, "::getDataFromPOST(%b)", bpeer)
|
||
|
||
// $1 -> ap (without localization => '@')
|
||
// $2 -> mac
|
||
// $3 -> ip
|
||
// $4 -> peer
|
||
// $5 -> old_label
|
||
// $6 -> old_mac
|
||
|
||
ip->clear();
|
||
mac->clear();
|
||
|
||
peer = U_NULLPTR;
|
||
|
||
UFlatBuffer fb, vec;
|
||
|
||
fb.setRoot(*UHTTP::body);
|
||
fb.AsVector(vec);
|
||
|
||
*ap = vec.AsVectorGet<UString>(0);
|
||
|
||
bool ok = setAccessPoint();
|
||
|
||
if (ok)
|
||
{
|
||
*mac = vec.AsVectorGet<UString>(1);
|
||
*ip = vec.AsVectorGet<UString>(2);
|
||
|
||
U_ASSERT(ip->isIPv4Addr())
|
||
U_ASSERT(mac->isXMacAddr())
|
||
|
||
if (bpeer)
|
||
{
|
||
peer = (void*) vec.AsVectorGet<uint64_t>(3);
|
||
|
||
UString mac_old = vec.AsVectorGet<UString>(5);
|
||
|
||
if (mac_old)
|
||
{
|
||
if (u_isXMacAddr(U_STRING_TO_PARAM(mac_old)) == false)
|
||
{
|
||
U_LOGGER("*** we have a change with a wrong old MAC(%V) ***", mac_old.rep);
|
||
|
||
U_RETURN(false);
|
||
}
|
||
|
||
UString label_old = vec.AsVectorGet<UString>(4);
|
||
|
||
// U_LOGGER("*** we have a change: MAC(%V) LABEL(%V) ***", mac_old.rep, label_old.rep);
|
||
|
||
if (getSession(mac_old, label_old, U_CONSTANT_TO_PARAM("getDataFromPOST(true)")))
|
||
{
|
||
deleteSession();
|
||
|
||
writeSessionToLOG(label_old, U_CONSTANT_TO_PARAM("DENY_NO_TRAFFIC"));
|
||
}
|
||
}
|
||
}
|
||
|
||
setSessionPolicy();
|
||
|
||
ok = checkDevice();
|
||
}
|
||
|
||
U_RETURN(ok);
|
||
}
|
||
|
||
static void addToLogout(const UString& label)
|
||
{
|
||
U_TRACE(5, "::addToLogout(%V)", label.rep)
|
||
|
||
// $1 -> ip
|
||
// $2 -> mac
|
||
// $3 -> apId
|
||
|
||
U_INTERNAL_DUMP("idx = %u", idx)
|
||
|
||
U_INTERNAL_ASSERT(*mac)
|
||
U_INTERNAL_ASSERT(label)
|
||
U_ASSERT(mac->isXMacAddr())
|
||
|
||
vec_logout[idx++] = ip_peer;
|
||
|
||
vmac->push_back(*mac);
|
||
vapID->push_back(label);
|
||
|
||
U_ASSERT_EQUALS( vmac->size(), idx)
|
||
U_ASSERT_EQUALS(vapID->size(), idx)
|
||
}
|
||
|
||
static void sendLogoutToNodog()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::sendLogoutToNodog()")
|
||
|
||
U_ASSERT_EQUALS( vmac->size(), idx)
|
||
U_ASSERT_EQUALS(vapID->size(), idx)
|
||
U_INTERNAL_ASSERT_RANGE(1,idx,sizeof(vec_logout))
|
||
|
||
UFlatBufferSpaceMedium space;
|
||
UFlatBuffer fb;
|
||
|
||
// $1 -> ip
|
||
// $2 -> mac
|
||
// $3 -> apId
|
||
|
||
fb.StartBuild();
|
||
(void) fb.StartVector();
|
||
|
||
for (uint32_t i = 0; i < idx; ++i)
|
||
{
|
||
fb.IPAddress(vec_logout[i]);
|
||
|
||
fb.String( vmac->at(i));
|
||
fb.String(vapID->at(i));
|
||
}
|
||
|
||
fb.EndVector(0, false);
|
||
(void) fb.EndBuild();
|
||
|
||
U_SRV_LOG("send request to nodog to logout %u users", idx);
|
||
|
||
(void) sendRequestToNodog(U_CONSTANT_TO_PARAM("logout"), fb.getResult());
|
||
|
||
idx = 0;
|
||
|
||
vmac->clear();
|
||
vapID->clear();
|
||
}
|
||
|
||
static void lostSession(int bclean)
|
||
{
|
||
U_TRACE(5, "::lostSession(%d)", bclean)
|
||
|
||
if (getSession(U_CONSTANT_TO_PARAM("lostSession")))
|
||
{
|
||
*ip = rc->getString(9);
|
||
*mac = rc->getString(8);
|
||
|
||
if (u_isIPv4Addr(U_STRING_TO_PARAM(*ip)) == false ||
|
||
u_isXMacAddr(U_STRING_TO_PARAM(*mac)) == false)
|
||
{
|
||
(void) rc->del(U_CONSTANT_TO_PARAM("SESSION:%v"), key_session->rep);
|
||
(void) rc->zrem(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate %v"), key_session->rep);
|
||
|
||
U_LOGGER("*** SESSION(%V) have a wrong IP(%V) or MAC(%V) ***", key_session->rep, ip->rep, mac->rep);
|
||
|
||
return;
|
||
}
|
||
|
||
if (bclean)
|
||
{
|
||
if (bclean == 2 &&
|
||
((u_now->tv_sec - lastUpdate) < U_ONE_HOUR_IN_SECOND))
|
||
{
|
||
return;
|
||
}
|
||
|
||
addr = rc->getULong(6);
|
||
*ap_label = rc->getString(7);
|
||
|
||
(void) rc->hmget(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u ip name"), addr);
|
||
|
||
U_INTERNAL_DUMP("idx = %u addr = %u old_addr = %u", idx, addr, old_addr)
|
||
|
||
if (old_addr != addr)
|
||
{
|
||
old_addr = addr;
|
||
|
||
if (idx) sendLogoutToNodog();
|
||
}
|
||
|
||
*ap_address = rc->getString(0);
|
||
*ap_hostname = rc->getString(1);
|
||
|
||
(void) UIPAddress::getBinaryForm(ip->c_str(), ip_peer);
|
||
|
||
addToLogout(*ap_label);
|
||
}
|
||
|
||
writeSessionToLOG(*ap_label, U_CONSTANT_TO_PARAM("DENY_LOST"));
|
||
|
||
deleteSession();
|
||
}
|
||
else
|
||
{
|
||
uint32_t pos = U_STRING_FIND(*key_session, 10, "deviceId:"); // 10 => U_CONSTANT_SIZE("captiveId:")
|
||
|
||
U_INTERNAL_ASSERT_DIFFERS(pos, U_NOT_FOUND)
|
||
|
||
const char* ptr = key_session->c_pointer(pos);
|
||
|
||
(void) rc->zrem(U_CONSTANT_TO_PARAM("SESSION:byCaptiveIdAndApId %.*s"), key_session->remain(ptr), ptr);
|
||
(void) rc->zrem(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate %v"), key_session->rep);
|
||
}
|
||
}
|
||
|
||
static void sessionClean(const UString& key)
|
||
{
|
||
U_TRACE(5, "::sessionClean(%V)", key.rep)
|
||
|
||
const char* ptr = key.c_pointer(U_CONSTANT_SIZE("SESSION:"));
|
||
|
||
key_session->setBuffer(200U);
|
||
|
||
key_session->snprintf(U_CONSTANT_TO_PARAM("%.*s"), key.remain(ptr), ptr);
|
||
|
||
lostSession(2);
|
||
}
|
||
|
||
static void GET_acceptTermsOfConditions()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_acceptTermsOfConditions()")
|
||
|
||
// $1 -> mac
|
||
|
||
if (UHTTP::processForm() == 2)
|
||
{
|
||
UHTTP::getFormValue(*mac, U_CONSTANT_TO_PARAM("mac"), 0, 1, 2);
|
||
|
||
if (mac->isMacAddr())
|
||
{
|
||
char buffer[16];
|
||
|
||
u_getXMAC(mac->data(), buffer);
|
||
|
||
(void) mac->replace(buffer, 12);
|
||
}
|
||
|
||
U_ASSERT(mac->isXMacAddr())
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("DEVICE:id:%v ExpirePrivacy %u"), mac->rep, u_now->tv_sec + duration_privacy_policy);
|
||
}
|
||
}
|
||
|
||
static void checkPrivacy(const UString& key)
|
||
{
|
||
U_TRACE(5, "::checkPrivacy(%V)", key.rep)
|
||
|
||
(void) rc->hmget(U_CONSTANT_TO_PARAM("%v ExpirePrivacy pNotify"), key.rep);
|
||
|
||
uint32_t expire = rc->getULong(0);
|
||
uint8_t policy = rc->getUInt8(1);
|
||
|
||
/**
|
||
* i) SE ["scadenza privacy policy" <= data corrente], ovvero <20> scaduta ALLORA [SET policy = "strict notify"] AND [SET "scadenza privacy policy" = null]
|
||
* (ovvero al prossimo accesso verr<72> ripresentata la richiesta di manifestazione del consenso)
|
||
*
|
||
* ii) SE ["scadenza privacy policy" = NULL] AND [policy = "notify"] ALLORA [SET policy = "strict notify"]
|
||
* (ovvero se si verifica che, per qualunque motivo, non <20> stato acquisito il consenso,
|
||
* allora al prossimo accesso di quel device-utente verr<72> ripresentata la richiesta tramite la pagina associata alla policy "strict notify")
|
||
*/
|
||
|
||
bool bexpired = (expire && expire <= u_now->tv_sec);
|
||
|
||
U_INTERNAL_DUMP("bexpired = %b expire = %u policy = %u", bexpired, expire, policy)
|
||
|
||
if (bexpired ||
|
||
(expire == 0 &&
|
||
policy != 2)) // strict notify
|
||
{
|
||
const char* op = "ENFORCING_STRICT_NOTIFY";
|
||
const char* ptr = key.c_pointer(U_CONSTANT_SIZE("DEVICE:id:"));
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("%v pNotify 2"), key.rep);
|
||
|
||
if (bexpired)
|
||
{
|
||
op = "EXPIRATION_PRIVACY_RENEWED";
|
||
|
||
(void) rc->hdel(U_CONSTANT_TO_PARAM("%v ExpirePrivacy"), key.rep);
|
||
}
|
||
|
||
ULog::log(facceptTermsOfConditionsRenew, U_CONSTANT_TO_PARAM("op: %s, mac: %.12s policy: %snotify, ExpirePrivacy: %#3D"), op, ptr, (policy == 0 ? "" :
|
||
policy == 1 ? "no_" : "strict_"), expire);
|
||
}
|
||
}
|
||
|
||
static void GET_acceptTermsOfConditionsRenew()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_acceptTermsOfConditionsRenew()")
|
||
|
||
if (UServer_Base::isLocalHost() == false) UHTTP::setBadRequest();
|
||
else
|
||
{
|
||
UString pathname(200U);
|
||
|
||
pathname.snprintf(U_CONSTANT_TO_PARAM("../log/acceptTermsOfConditionsRenew.%4D.log"), 0);
|
||
|
||
facceptTermsOfConditionsRenew = UFile::creat(pathname.data(), O_TRUNC | O_WRONLY | O_APPEND);
|
||
|
||
(void) rc->scan(checkPrivacy, U_CONSTANT_TO_PARAM("DEVICE:id:*"));
|
||
|
||
UFile::close(facceptTermsOfConditionsRenew);
|
||
}
|
||
}
|
||
|
||
static void GET_anagrafica()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_anagrafica()")
|
||
|
||
if (UServer_Base::isLocalHost() == false) UHTTP::setBadRequest();
|
||
else
|
||
{
|
||
loadAnagrafica();
|
||
}
|
||
}
|
||
|
||
static void GET_checkCaptive()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_checkCaptive()")
|
||
|
||
if (UServer_Base::isLocalHost() == false) UHTTP::setBadRequest();
|
||
else
|
||
{
|
||
(void) rc->zrangebyscore(U_CONSTANT_TO_PARAM("CAPTIVE:byLastUpdate 0 %u"), u_now->tv_sec - U_CLEAN_INTERVAL);
|
||
|
||
uint32_t n = rc->vitem.size();
|
||
|
||
if (n)
|
||
{
|
||
uint8_t status;
|
||
UString url(100U);
|
||
UVector<UString> vec(n);
|
||
|
||
vec.copy(rc->vitem);
|
||
|
||
for (uint32_t i = 0; i < n; ++i)
|
||
{
|
||
*ap_address = vec[i];
|
||
|
||
(void) UIPAddress::getBinaryForm(ap_address->c_str(), addr, true);
|
||
|
||
url.snprintf(U_CONSTANT_TO_PARAM("http://%v:5280/ping"), ap_address->rep);
|
||
|
||
// NB: we need PREFORK_CHILD > 2
|
||
|
||
if (client->connectServer(url) &&
|
||
client->sendRequest())
|
||
{
|
||
status = '3';
|
||
|
||
client->UClient_Base::close();
|
||
}
|
||
else
|
||
{
|
||
status = '0'; // NB: nodog not respond
|
||
|
||
if (sockp)
|
||
{
|
||
UIPAddress laddr;
|
||
|
||
if (client->remoteIPAddress(laddr) &&
|
||
sockp->ping(laddr))
|
||
{
|
||
status = '2'; // NB: nodog not respond but pingable => unreachable...
|
||
}
|
||
}
|
||
}
|
||
|
||
client->reset();
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u status %c"), addr, status);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void GET_clean()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_clean()")
|
||
|
||
if (UServer_Base::isLocalHost() == false) UHTTP::setBadRequest();
|
||
else
|
||
{
|
||
old_addr = 0;
|
||
|
||
(void) rc->zrangebyscore(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate 0 %u"), u_now->tv_sec - U_CLEAN_INTERVAL);
|
||
|
||
uint32_t n = rc->vitem.size();
|
||
|
||
if (n)
|
||
{
|
||
UVector<UString> vec(n);
|
||
|
||
vec.copy(rc->vitem);
|
||
|
||
for (uint32_t i = 0; i < n; ++i)
|
||
{
|
||
*key_session = vec[i];
|
||
|
||
lostSession(1);
|
||
}
|
||
}
|
||
|
||
U_INTERNAL_DUMP("idx = %u", idx)
|
||
|
||
if (idx) sendLogoutToNodog();
|
||
}
|
||
}
|
||
|
||
static void GET_cleanSession()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_cleanSession()")
|
||
|
||
if (UServer_Base::isLocalHost() == false) UHTTP::setBadRequest();
|
||
else
|
||
{
|
||
old_addr = 0;
|
||
|
||
(void) rc->scan(sessionClean, U_CONSTANT_TO_PARAM("SESSION:captiveId:*"));
|
||
|
||
U_INTERNAL_DUMP("idx = %u", idx)
|
||
|
||
if (idx) sendLogoutToNodog();
|
||
}
|
||
}
|
||
|
||
static void GET_get_config()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_get_config()")
|
||
|
||
// $1 -> ap (without localization => '@')
|
||
// $2 -> key
|
||
|
||
UString body;
|
||
|
||
if (UHTTP::processForm() == 2*2)
|
||
{
|
||
UString key;
|
||
|
||
UHTTP::getFormValue(key, U_CONSTANT_TO_PARAM("key"), 0, 3, 4);
|
||
|
||
if (key)
|
||
{
|
||
UString buffer(U_CAPACITY);
|
||
|
||
buffer.snprintf(U_CONSTANT_TO_PARAM("../ap/%v/nodog.conf"), key.rep);
|
||
|
||
body = UFile::contentOf(buffer);
|
||
|
||
if (body.empty())
|
||
{
|
||
body = *nodog_conf;
|
||
|
||
UHTTP::getFormValue(*ap, U_CONSTANT_TO_PARAM("ap"), 0, 1, 4);
|
||
|
||
UVector<UString> vec_subst;
|
||
|
||
vec_subst.push_back(U_STRING_FROM_CONSTANT("<LAN>"));
|
||
|
||
if (UStringExt::endsWith(*ap, U_CONSTANT_TO_PARAM("_pico2"))) vec_subst.push_back(U_STRING_FROM_CONSTANT("ath0"));
|
||
else if (UStringExt::endsWith(*ap, U_CONSTANT_TO_PARAM("_x86"))) vec_subst.push_back(U_STRING_FROM_CONSTANT("eth1"));
|
||
else if (UStringExt::endsWith(*ap, U_CONSTANT_TO_PARAM("_rspro")))
|
||
{
|
||
if (UStringExt::startsWith(*ap, U_CONSTANT_TO_PARAM("wimo"))) vec_subst.push_back(U_STRING_FROM_CONSTANT("br-lan"));
|
||
else vec_subst.push_back(U_STRING_FROM_CONSTANT("eth1"));
|
||
}
|
||
else
|
||
{
|
||
vec_subst.push_back(U_STRING_FROM_CONSTANT("wlan0")); // ..._picoM2, ..._locoM2, ..._bulletM2, ..._unifiAP
|
||
}
|
||
|
||
if (u_isIPv4Addr(U_STRING_TO_PARAM(key))) *ap_address = key;
|
||
else (void) ap_address->assign(U_CLIENT_ADDRESS_TO_PARAM);
|
||
|
||
buffer.snprintf(U_CONSTANT_TO_PARAM("../ap/%v/nodog.conf.local"), ap_address->rep);
|
||
|
||
UVector<UString> vec(*ap_address, '.');
|
||
UString lbl, netmask, local = UFile::contentOf(buffer), address_mask(32U);
|
||
|
||
address_mask.snprintf(U_CONSTANT_TO_PARAM("%u.%v"), 16 + vec[2].strtoul(), vec[3].rep);
|
||
|
||
if (setLabelAndNetmaskFromAnagrafica(lbl, netmask))
|
||
{
|
||
buffer.snprintf(U_CONSTANT_TO_PARAM("LOCAL_NETWORK_LABEL \"%v\""), lbl.rep);
|
||
|
||
vec_subst.push_back(U_STRING_FROM_CONSTANT("LOCAL_NETWORK_LABEL ap"));
|
||
vec_subst.push_back(buffer);
|
||
|
||
if (local)
|
||
{
|
||
UString tmp(200U + local.size() + netmask.size() + lbl.size());
|
||
|
||
tmp.snprintf(U_STRING_TO_PARAM(local), netmask.rep, lbl.rep);
|
||
|
||
local = tmp;
|
||
}
|
||
}
|
||
|
||
vec_subst.push_back(U_STRING_FROM_CONSTANT("#include \"../ap/<AAA.BBB.CCC.DDD>/nodog.conf.local\""));
|
||
vec_subst.push_back(local);
|
||
vec_subst.push_back(U_STRING_FROM_CONSTANT("<AAA.BBB.CCC.DDD>"));
|
||
vec_subst.push_back(*ap_address);
|
||
vec_subst.push_back(U_STRING_FROM_CONSTANT("<CCC>.<DDD>"));
|
||
vec_subst.push_back(address_mask);
|
||
|
||
UFileConfig cfg(UStringExt::substitute(body, vec_subst), true);
|
||
|
||
UHTTP::mime_index = U_know;
|
||
|
||
if (cfg.processData(false)) body = cfg.getData();
|
||
}
|
||
}
|
||
}
|
||
|
||
UHTTP::setResponseBody(body);
|
||
}
|
||
|
||
static void GET_logout()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_logout()")
|
||
|
||
if (UServer_Base::isLocalHost() == false) UHTTP::setBadRequest();
|
||
else
|
||
{
|
||
// $1 -> ap (with localization => '@')
|
||
// $2 -> ip
|
||
// $3 -> mac
|
||
|
||
if (UHTTP::processForm() == 3*2)
|
||
{
|
||
ip->clear();
|
||
ap->clear();
|
||
mac->clear();
|
||
|
||
UHTTP::getFormValue(*ap, U_CONSTANT_TO_PARAM("ap"), 0, 1, 6);
|
||
|
||
if (setAccessPoint())
|
||
{
|
||
UHTTP::getFormValue(*ip, U_CONSTANT_TO_PARAM("ip"), 0, 3, 6);
|
||
|
||
if (ip->isIPv4Addr())
|
||
{
|
||
UHTTP::getFormValue(*mac, U_CONSTANT_TO_PARAM("mac"), 0, 5, 6);
|
||
|
||
if (mac->isMacAddr())
|
||
{
|
||
char buffer[16];
|
||
|
||
u_getXMAC(mac->data(), buffer);
|
||
|
||
(void) mac->replace(buffer, 12);
|
||
}
|
||
|
||
U_ASSERT(mac->isXMacAddr())
|
||
|
||
if (getSession(*mac, *ap_label, U_CONSTANT_TO_PARAM("GET_logout")))
|
||
{
|
||
(void) UIPAddress::getBinaryForm(ip->c_str(), ip_peer);
|
||
|
||
idx = 0;
|
||
|
||
addToLogout(*ap_label);
|
||
|
||
sendLogoutToNodog();
|
||
|
||
writeSessionToLOG(*ap_label, U_CONSTANT_TO_PARAM("DENY_NO_TRAFFIC"));
|
||
|
||
deleteSession();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void GET_start_ap()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_start_ap()")
|
||
|
||
/**
|
||
* $1 -> ap (with localization => '@')
|
||
* $2 -> public address to contact the access point
|
||
* $3 -> pid (0 => start)
|
||
* $4 -> uptime
|
||
*
|
||
* GET /start_ap?ap=1000@192.168.42.136/stefano&public=U2FsdGVkX1-UKZ7S9pzvcFnzkMVr_P428Pw7Cf_Ptm8%3A5280&pid=-1&uptime=1234567890
|
||
*/
|
||
|
||
if (UHTTP::processForm() == 4*2)
|
||
{
|
||
ap->clear();
|
||
|
||
UHTTP::getFormValue(*ap, U_CONSTANT_TO_PARAM("ap"), 0, 1, 8);
|
||
|
||
bool ok = setAccessPoint();
|
||
|
||
if (ok)
|
||
{
|
||
uint32_t pos;
|
||
UString address;
|
||
|
||
UHTTP::getFormValue(address, U_CONSTANT_TO_PARAM("public"), 0, 3, 8);
|
||
|
||
if (address)
|
||
{
|
||
pos = address.find(':');
|
||
|
||
if (pos == U_NOT_FOUND ||
|
||
address.substr(pos+1).strtoul() != 5280)
|
||
{
|
||
U_LOGGER("*** CAPTIVE ADDRESS_PUBLIC(%v) NOT VALID ***", address.rep);
|
||
|
||
return;
|
||
}
|
||
|
||
UString IP_address_trust = address.substr(0U, pos).copy();
|
||
|
||
if (IP_address_trust.isBase64Url() == false)
|
||
{
|
||
U_LOGGER("*** CAPTIVE ADDRESS_TRUST(%v) NOT BASE64 ***", IP_address_trust.rep);
|
||
|
||
return;
|
||
}
|
||
|
||
address = UDES3::getSignedData(IP_address_trust);
|
||
|
||
if (u_isIPv4Addr(U_STRING_TO_PARAM(address)) == false)
|
||
{
|
||
U_LOGGER("*** CAPTIVE ADDRESS_TRUST(%v) NOT VALID ***", IP_address_trust.rep);
|
||
|
||
return;
|
||
}
|
||
|
||
if (ap_address->equal(address) == false)
|
||
{
|
||
U_LOGGER("*** CAPTIVE ADDRESS(%v) NOT EQUAL TO %V ***", ap_address->rep, address.rep);
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
UString x(200U);
|
||
|
||
x.snprintf(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u"), addr);
|
||
|
||
if (rc->exists(U_STRING_TO_PARAM(x)) == false)
|
||
{
|
||
U_LOGGER("*** %v NOT FOUND ***", x.rep);
|
||
|
||
return;
|
||
}
|
||
|
||
uint32_t n;
|
||
char buffer[1024];
|
||
UString pid, uptime;
|
||
|
||
UHTTP::getFormValue(pid, U_CONSTANT_TO_PARAM("pid"), 0, 5, 8);
|
||
UHTTP::getFormValue(uptime, U_CONSTANT_TO_PARAM("uptime"), 0, 7, 8);
|
||
|
||
U_LOGGER("%.*s %s", getApInfo(*ap_label, buffer), buffer, pid.strtol() == -1 ? "started" : "*** NODOG CRASHED ***");
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u name %v status 1 uptime %v since %u lastUpdate %u"), addr, ap_hostname->rep, uptime.rep, u_now->tv_sec, u_now->tv_sec);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("CAPTIVE:byLastUpdate %u %v"), u_now->tv_sec, ap_address->rep);
|
||
|
||
x.snprintf(U_CONSTANT_TO_PARAM("%u"), addr);
|
||
|
||
loop: (void) rc->zrangebyscore(U_CONSTANT_TO_PARAM("SESSION:byCaptiveIdAndApId %v000000 %v999999 WITHSCORES LIMIT 0 500"), x.rep, x.rep);
|
||
|
||
n = rc->vitem.size();
|
||
|
||
if (n >= 2)
|
||
{
|
||
uint32_t j;
|
||
const char* ptr;
|
||
UString tmp(200U);
|
||
UVector<UString> vec(n);
|
||
|
||
vec.copy(rc->vitem);
|
||
|
||
key_session->setBuffer(200U);
|
||
|
||
tmp.snprintf(U_CONSTANT_TO_PARAM("captiveId:%u;apId:"), addr);
|
||
|
||
for (int32_t i = 0; i < (int32_t)n; i += 2)
|
||
{
|
||
ptr = vec[i+1].pend()-6; // score (ex: 3232246838000064)
|
||
|
||
for (j = 0; j < 6 && (ptr[j] == '0'); ++j) {}
|
||
|
||
if (j == 6) key_session->snprintf(U_CONSTANT_TO_PARAM("%v0;%v"), tmp.rep, vec[i].rep);
|
||
else
|
||
{
|
||
(void) ap_label->assign(ptr+j, 6-j);
|
||
|
||
key_session->snprintf(U_CONSTANT_TO_PARAM("%v%v;%v"), tmp.rep, ap_label->rep, vec[i].rep);
|
||
}
|
||
|
||
lostSession(0);
|
||
}
|
||
|
||
goto loop;
|
||
}
|
||
}
|
||
}
|
||
|
||
UHTTP::setResponseBody(*allowed_web_hosts);
|
||
}
|
||
|
||
static void GET_welcome()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::GET_welcome()")
|
||
|
||
// $1 -> url
|
||
// $2 -> mac
|
||
// $3 -> apid
|
||
// $4 -> gateway
|
||
|
||
bool ok = false;
|
||
|
||
if (UHTTP::processForm() == 4*2)
|
||
{
|
||
UHTTP::getFormValue(*mac, U_CONSTANT_TO_PARAM("mac"), 0, 3, 8);
|
||
|
||
if (mac->isXMacAddr())
|
||
{
|
||
UHTTP::getFormValue(*ap_label, U_CONSTANT_TO_PARAM("apid"), 0, 5, 8);
|
||
|
||
setSessionPolicy();
|
||
|
||
ok = checkDevice();
|
||
}
|
||
}
|
||
|
||
if (ok == false) UHTTP::setResponseFromFileCache(deny_html);
|
||
else
|
||
{
|
||
// policy: (DAILY|FLAT), SessionNotify: (0,notify) (1,no_notify) (2,strict_notify)
|
||
|
||
uint8_t index = vwelcome_index[policySessionId->equal(U_CONSTANT_TO_PARAM("FLAT"))][policySessionNotify];
|
||
|
||
U_INTERNAL_DUMP("index = %u policySessionId = %V policySessionNotify = %u", index, policySessionId->rep, policySessionNotify)
|
||
|
||
UString x = vwelcome_file->at(index);
|
||
|
||
UHTTP::UFileCacheData* welcome_html = UHTTP::getFileCachePointer(U_STRING_TO_PARAM(x));
|
||
|
||
U_INTERNAL_ASSERT_POINTER(welcome_html)
|
||
|
||
UHTTP::setResponseFromFileCache(welcome_html);
|
||
}
|
||
|
||
U_http_info.nResponseCode = HTTP_NO_CONTENT; // NB: to escape management after usp exit...
|
||
}
|
||
|
||
static void POST_login()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::POST_login()")
|
||
|
||
// $1 -> ap (with localization => '@')
|
||
// $2 -> mac
|
||
// $3 -> ip
|
||
// $4 -> peer
|
||
// $5 -> old_label
|
||
// $6 -> old_mac
|
||
|
||
bool ko = (getDataFromPOST(true) == false);
|
||
|
||
if (*mac)
|
||
{
|
||
UFlatBuffer fb;
|
||
char buffer[2] = { '1'-ko, '0'+policySessionNotify }; // deny|permit: ('0'|'1') policy: notify|no_notify|strict_notify ('0'|'1'|'2')
|
||
|
||
writeToLOG(*ap_label, U_CONSTANT_TO_PARAM("PERMIT"), UString::getStringNull());
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("DEVICE:id:%v lastAccess %u"), mac->rep, u_now->tv_sec);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("DEVICE:bylastAccess %u id:%v"), u_now->tv_sec, mac->rep);
|
||
|
||
if (ko) writeSessionToLOG(*ap_label, U_CONSTANT_TO_PARAM("DENY_POLICY"));
|
||
else
|
||
{
|
||
U_ASSERT(mac->isXMacAddr())
|
||
|
||
setSessionKey(*mac, *ap_label);
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("SESSION:%v captiveId %u apId %v deviceId %v ip %v created %u pId %v notify %c consume %c counter 0 lastUpdate %u"), key_session->rep,
|
||
addr, ap_label->rep, mac->rep, ip->rep, u_now->tv_sec, policySessionId->rep, buffer[1], '0'+ap_consume, u_now->tv_sec);
|
||
|
||
// U_LOGGER("*** SESSION(%V) created at POST_login() ***", key_session->rep);
|
||
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("SESSION:byCaptiveIdAndApId %u%06u deviceId:%v;ip:%v"), addr, ap_label->strtoul(), mac->rep, ip->rep);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate %u %v"), u_now->tv_sec, key_session->rep);
|
||
}
|
||
|
||
U_INTERNAL_DUMP("peer = %p", peer)
|
||
|
||
if (peer)
|
||
{
|
||
// $1 -> peer
|
||
// $2 -> deny|permit: ('0'|'1') policy: notify|no_notify|strict_notify ('0'|'1'|'2')
|
||
|
||
# ifdef HAVE_CXX11
|
||
(void) fb.encodeVector([&]() {
|
||
fb.UInt(U_PTR2INT(peer));
|
||
fb.String(buffer, sizeof(buffer));
|
||
});
|
||
# else
|
||
fb.StartBuild();
|
||
(void) fb.StartVector();
|
||
|
||
fb.UInt(U_PTR2INT(peer));
|
||
fb.String(buffer, sizeof(buffer));
|
||
|
||
fb.EndVector(0, false);
|
||
(void) fb.EndBuild();
|
||
# endif
|
||
|
||
(void) sendRequestToNodog(U_CONSTANT_TO_PARAM("login_validate"), fb.getResult());
|
||
}
|
||
}
|
||
|
||
ap->clear();
|
||
|
||
resetAccessPoint();
|
||
}
|
||
|
||
static void POST_notify()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::POST_notify()")
|
||
|
||
// $1 -> ap (with localization => '@')
|
||
// $2 -> mac
|
||
// $3 -> ip
|
||
|
||
if (getDataFromPOST(false)) writeToLOG(*ap_label, U_CONSTANT_TO_PARAM("NOTIFIED"), UString::getStringNull());
|
||
|
||
ap->clear();
|
||
|
||
resetAccessPoint();
|
||
}
|
||
|
||
static void POST_strict_notify()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::POST_strict_notify()")
|
||
|
||
// $1 -> ap (with localization => '@')
|
||
// $2 -> mac
|
||
// $3 -> ip
|
||
|
||
if (getDataFromPOST(false))
|
||
{
|
||
UString x(200U);
|
||
|
||
x.snprintf(U_CONSTANT_TO_PARAM("DEVICE:id:%v pNotify"), mac->rep);
|
||
|
||
(void) rc->hmget(x);
|
||
|
||
if (rc->getUInt8() == 2) // (strict notify) => (notify)
|
||
{
|
||
(void) x.append(U_CONSTANT_TO_PARAM(" 0"));
|
||
|
||
(void) rc->hmset(x);
|
||
}
|
||
|
||
writeToLOG(*ap_label, U_CONSTANT_TO_PARAM("STRICT_NOTIFIED"), UString::getStringNull());
|
||
}
|
||
|
||
ap->clear();
|
||
|
||
resetAccessPoint();
|
||
}
|
||
|
||
/*
|
||
$1 -> mac
|
||
$2 -> ip
|
||
$3 -> apId
|
||
$4 -> time
|
||
$5 -> traffic
|
||
$6 -> time_no_traffic
|
||
|
||
struct PostInfo {
|
||
|
||
UString ip, mac, label;
|
||
uint32_t _ctime, ctraffic, time_no_traffic;
|
||
|
||
void clear()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "PostInfo::clear()")
|
||
|
||
ip.clear();
|
||
mac.clear();
|
||
label.clear();
|
||
|
||
_ctime = ctraffic = time_no_traffic = 0;
|
||
}
|
||
|
||
void fromFlatBuffer(UFlatBuffer& fb)
|
||
{
|
||
U_TRACE(5, "PostInfo::fromFlatBuffer(%p)", &fb)
|
||
|
||
fb.fromFlatBuffer(0, FLATBUFFER(ip, UString));
|
||
fb.fromFlatBuffer(1, FLATBUFFER(mac, UString));
|
||
fb.fromFlatBuffer(2, FLATBUFFER(label, UString));
|
||
fb.fromFlatBuffer(3, FLATBUFFER(_ctime, uint32_t));
|
||
fb.fromFlatBuffer(4, FLATBUFFER(ctraffic, uint32_t));
|
||
fb.fromFlatBuffer(5, FLATBUFFER(time_no_traffic, uint32_t));
|
||
}
|
||
};
|
||
*/
|
||
|
||
static void POST_info()
|
||
{
|
||
U_TRACE_NO_PARAM(5, "::POST_info()")
|
||
|
||
U_INTERNAL_DUMP("UHTTP::body(%u) = %#V", UHTTP::body->size(), UHTTP::body->rep)
|
||
|
||
UFlatBuffer fb, vec;
|
||
|
||
fb.setRoot(*UHTTP::body);
|
||
fb.AsVector(vec);
|
||
|
||
*ap = vec.AsVectorGet<UString>(0);
|
||
|
||
if (setAccessPoint())
|
||
{
|
||
const char* op;
|
||
UString x(200U), label;
|
||
uint32_t ctraffic, ctime_no_traffic, op_len, midnigth = u_getLocalTime() / U_ONE_DAY_IN_SECOND; // _ctime, time_no_traffic
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u status 1 lastUpdate %u"), addr, u_now->tv_sec);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("CAPTIVE:byLastUpdate %u %v"), u_now->tv_sec, ap_address->rep);
|
||
|
||
for (int32_t i = 1, n = (int32_t) vec.GetSize(); i < n; i += 4)
|
||
{
|
||
// -----------------------------------------------------------------------------------------------------------------------------------------
|
||
// $1 -> mac
|
||
// $2 -> ip
|
||
// $3 -> apId
|
||
// $4 -> traffic
|
||
// ---------------------
|
||
// $5 -> time
|
||
// $6 -> time_no_traffic
|
||
// -----------------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
*mac = vec.AsVectorGet<UString>(i);
|
||
ip_peer = vec.AsVectorGetIPAddress(i+1);
|
||
label = vec.AsVectorGet<UString>(i+2);
|
||
ctraffic = vec.AsVectorGet<uint32_t>(i+3);
|
||
|
||
/*
|
||
_ctime = vec.AsVectorGet<uint32_t>(i+4);
|
||
time_no_traffic = vec.AsVectorGet<uint32_t>(i+5);
|
||
*/
|
||
|
||
*ip = UIPAddress::toString(ip_peer);
|
||
|
||
U_INTERNAL_DUMP("apId = %V mac = %V ip = %V ctraffic = %u", label.rep, mac->rep, ip->rep, ctraffic)
|
||
|
||
if (mac->empty())
|
||
{
|
||
U_LOGGER("*** INFO (apId = %V mac = \"\" ip = %V ctraffic = %u) NOT VALID ***", label.rep, ip->rep, ctraffic);
|
||
|
||
continue;
|
||
}
|
||
|
||
if (getSession(*mac, label, U_CONSTANT_TO_PARAM("POST_info")) == false) goto del_login;
|
||
|
||
U_INTERNAL_DUMP("apId = %V mac = %V ip = %V", rc->getString(7).rep, rc->getString(8).rep, rc->getString(9).rep)
|
||
|
||
U_ASSERT_EQUALS(label, rc->getString(7))
|
||
U_ASSERT_EQUALS(*mac, rc->getString(8))
|
||
U_ASSERT_EQUALS(*ip, rc->getString(9))
|
||
|
||
if (addr != rc->getULong(6))
|
||
{
|
||
U_LOGGER("*** SESSION(%V) DIFFER FOR ADDR (%u => %u) ***", key_session->rep, addr, rc->getULong(6));
|
||
}
|
||
|
||
if (ctraffic == 0)
|
||
{
|
||
ctime_no_traffic = (u_now->tv_sec - lastUpdate);
|
||
|
||
U_DEBUG("Peer IP %v MAC %v has made no traffic for %u secs", ip->rep, mac->rep, ctime_no_traffic);
|
||
|
||
if (ctime_no_traffic >= U_MAX_TIME_NO_TRAFFIC) // (time_no_traffic >= U_MAX_TIME_NO_TRAFFIC)
|
||
{
|
||
op = "DENY_NO_TRAFFIC";
|
||
op_len = U_CONSTANT_SIZE("DENY_NO_TRAFFIC");
|
||
|
||
created += ctime_no_traffic;
|
||
|
||
del_sess: writeSessionToLOG(label, op, op_len);
|
||
|
||
deleteSession();
|
||
|
||
del_login: addToLogout(label);
|
||
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if ((u_get_localtime(lastUpdate) / U_ONE_DAY_IN_SECOND) < midnigth)
|
||
{
|
||
if (policySessionId->equal(U_CONSTANT_TO_PARAM("DAILY"))) resetDeviceDailyCounter();
|
||
|
||
if (counter)
|
||
{
|
||
x.snprintf(U_CONSTANT_TO_PARAM(", traffic: %llu"), counter/1024);
|
||
|
||
writeToLOG(*ap_label, U_CONSTANT_TO_PARAM("RST_SESSION"), x);
|
||
|
||
counter = 0;
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("SESSION:%v counter 0"), key_session->rep);
|
||
}
|
||
}
|
||
|
||
if (ctraffic)
|
||
{
|
||
counter += ctraffic;
|
||
|
||
if (ap_consume &&
|
||
policySessionId->equal(U_CONSTANT_TO_PARAM("DAILY")) &&
|
||
rc->hincrby(U_CONSTANT_TO_PARAM("DEVICE:id:%v pCounter %u"), mac->rep, ctraffic) >= max_traffic_daily)
|
||
{
|
||
op = "DENY_POLICY";
|
||
op_len = U_CONSTANT_SIZE("DENY_POLICY");
|
||
|
||
goto del_sess;
|
||
}
|
||
|
||
(void) rc->hmset(U_CONSTANT_TO_PARAM("SESSION:%v counter %llu lastUpdate %u"), key_session->rep, counter, u_now->tv_sec);
|
||
(void) rc->zadd(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate %u %v"), u_now->tv_sec, key_session->rep);
|
||
}
|
||
}
|
||
|
||
U_INTERNAL_DUMP("idx = %u", idx)
|
||
|
||
if (idx) sendLogoutToNodog();
|
||
}
|
||
|
||
ap->clear();
|
||
|
||
resetAccessPoint();
|
||
}
|
||
#endif
|