mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +01:00
new files to track how long it's been since data's been received from
a UDP address. The idea's that when there's too long a gap the address has likely been recycled and we shouldn't send replies to packets received before the reset.
This commit is contained in:
parent
6418513a6d
commit
acca4d14d4
5 changed files with 156 additions and 2 deletions
|
@ -34,6 +34,7 @@ SRC = \
|
|||
devmgr.cpp \
|
||||
udpqueue.cpp \
|
||||
udpack.cpp \
|
||||
udpager.cpp \
|
||||
xwrelay.cpp \
|
||||
|
||||
# STATIC ?= -static
|
||||
|
|
89
xwords4/relay/udpager.cpp
Normal file
89
xwords4/relay/udpager.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/* -*- compile-command: "make -k -j3"; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2013 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "udpager.h"
|
||||
#include "configs.h"
|
||||
#include "mlock.h"
|
||||
|
||||
static UDPAger* s_instance = NULL;
|
||||
|
||||
/* static */ UDPAger*
|
||||
UDPAger::Get()
|
||||
{
|
||||
if ( NULL == s_instance ) {
|
||||
s_instance = new UDPAger();
|
||||
}
|
||||
return s_instance;
|
||||
} /* Get */
|
||||
|
||||
UDPAger::UDPAger()
|
||||
{
|
||||
if ( !RelayConfigs::GetConfigs()-> GetValueFor( "UDP_RECYLE_INTERVAL",
|
||||
&m_maxInterval ) ) {
|
||||
assert(0);
|
||||
}
|
||||
logf( XW_LOGINFO, "read %d from configs for UDP_RECYLE_INTERVAL",
|
||||
m_maxInterval );
|
||||
m_maxInterval *= 1000; // make it milliseconds
|
||||
|
||||
pthread_mutex_init( &m_addrTimeMapLock, NULL );
|
||||
}
|
||||
|
||||
// An address is valid as long as we keep hearing from it within a certain
|
||||
// frequency. When we hear from it but it's been too long, assume it's new
|
||||
// and give it a new timestamp.
|
||||
void
|
||||
UDPAger::Refresh( const AddrInfo* addr )
|
||||
{
|
||||
const AddrInfo::AddrUnion* saddr = addr->saddr();
|
||||
uint32_t readWhen = addr->created();
|
||||
gchar* b64 = g_base64_encode( (unsigned char*)&saddr->u.addr,
|
||||
sizeof(saddr->u.addr) );
|
||||
|
||||
MutexLock ml( &m_addrTimeMapLock );
|
||||
|
||||
map<AddrInfo::AddrUnion, AgePair*>::iterator iter =
|
||||
m_addrTimeMap.find( *saddr );
|
||||
if ( m_addrTimeMap.end() == iter ) { // it's new; just insert
|
||||
AgePair* ap = new AgePair( readWhen, readWhen );
|
||||
m_addrTimeMap.insert( pair<AddrInfo::AddrUnion,
|
||||
AgePair*>(*saddr, ap ) );
|
||||
logf( XW_LOGINFO, "%s: adding '%s'", __func__, b64 );
|
||||
} else {
|
||||
AgePair* ap = iter->second;
|
||||
assert( ap->lastSeen() <= readWhen );
|
||||
int interval = readWhen - ap->lastSeen();
|
||||
if ( m_maxInterval >= interval ) {
|
||||
logf( XW_LOGINFO, "%s: refreshing '%s'; last seen %d "
|
||||
"milliseconds ago", __func__, b64, interval );
|
||||
ap->update( readWhen );
|
||||
} else {
|
||||
logf( XW_LOGINFO, "%s: RESETTING '%s'; last seen %d "
|
||||
"milliseconds ago", __func__, b64, interval );
|
||||
delete ap;
|
||||
iter->second = new AgePair( readWhen, readWhen );
|
||||
}
|
||||
}
|
||||
|
||||
g_free( b64 );
|
||||
}
|
||||
|
60
xwords4/relay/udpager.h
Normal file
60
xwords4/relay/udpager.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 2013 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _UDPAGER_H_
|
||||
#define _UDPAGER_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "addrinfo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class UDPAger {
|
||||
public:
|
||||
static UDPAger* Get();
|
||||
UDPAger();
|
||||
void Refresh( const AddrInfo* addr );
|
||||
|
||||
private:
|
||||
|
||||
class AgePair {
|
||||
public:
|
||||
AgePair( uint32_t created, uint32_t lastSeen ) {
|
||||
m_created = created;
|
||||
m_lastSeen = lastSeen;
|
||||
}
|
||||
void update( uint32_t lastSeen ) { m_lastSeen = lastSeen; }
|
||||
uint32_t lastSeen() { return m_lastSeen; }
|
||||
private:
|
||||
uint32_t m_created;
|
||||
uint32_t m_lastSeen;
|
||||
};
|
||||
|
||||
/* Map socket addresses against times, moving the time forward only
|
||||
when it's been too long since we saw it. */
|
||||
int m_maxInterval; /* config: how long since we heard */
|
||||
|
||||
map<AddrInfo::AddrUnion, AgePair*> m_addrTimeMap;
|
||||
pthread_mutex_t m_addrTimeMapLock;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -27,7 +27,9 @@ GAME_PORTS=10997
|
|||
DEVICE_PORTS=10998
|
||||
|
||||
# Port for per-device UDP interface (experimental)
|
||||
UDPPORT=10997
|
||||
UDP_PORT=10997
|
||||
# How long after we've read from an address before we assume it's recycled
|
||||
UDP_RECYLE_INTERVAL=60
|
||||
|
||||
# default 5
|
||||
SOCK_TIMEOUT_SECONDS=5
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
#include "devmgr.h"
|
||||
#include "udpqueue.h"
|
||||
#include "udpack.h"
|
||||
#include "udpager.h"
|
||||
|
||||
typedef struct _UDPHeader {
|
||||
uint32_t packetID;
|
||||
|
@ -1499,6 +1500,7 @@ read_udp_packet( int udpsock )
|
|||
#endif
|
||||
|
||||
AddrInfo addr( udpsock, &saddr, false );
|
||||
UDPAger::Get()->Refresh( &addr );
|
||||
UdpQueue::get()->handle( &addr, buf, nRead, handle_udp_packet );
|
||||
}
|
||||
}
|
||||
|
@ -1744,7 +1746,7 @@ main( int argc, char** argv )
|
|||
(void)cfg->GetValueFor( "CTLPORT", &ctrlport );
|
||||
}
|
||||
if ( -1 == udpport ) {
|
||||
(void)cfg->GetValueFor( "UDPPORT", &udpport );
|
||||
(void)cfg->GetValueFor( "UDP_PORT", &udpport );
|
||||
}
|
||||
#ifdef DO_HTTP
|
||||
if ( httpport == 0 ) {
|
||||
|
|
Loading…
Add table
Reference in a new issue