Merge remote branch 'origin/android_branch' into android_branch

This commit is contained in:
Eric House 2012-01-04 18:16:32 -08:00
commit 4a8a52a921
11 changed files with 156 additions and 90 deletions

2
xwords4/debian/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.ex

View file

@ -1,7 +1,7 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/* -*- compile-command: "make -j3"; -*- */
/*
* Copyright 2005-2009 by Eric House (xwords@eehouse.org). All rights
* Copyright 2005 - 2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -180,7 +180,7 @@ CookieRef::Unlock() {
bool
CookieRef::_Connect( int socket, int nPlayersH, int nPlayersS, int seed,
bool seenSeed )
bool seenSeed, in_addr& addr )
{
bool connected = false;
HostID prevHostID = HOST_ID_NONE;
@ -199,7 +199,7 @@ CookieRef::_Connect( int socket, int nPlayersH, int nPlayersS, int seed,
if ( !connected ) {
set<int> sockets = GetSockets();
if ( sockets.end() == sockets.find( socket ) ) {
pushConnectEvent( socket, nPlayersH, nPlayersS, seed );
pushConnectEvent( socket, nPlayersH, nPlayersS, seed, addr );
handleEvents();
connected = HasSocket_locked( socket );
} else {
@ -211,7 +211,7 @@ CookieRef::_Connect( int socket, int nPlayersH, int nPlayersS, int seed,
bool
CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersS,
int seed, bool gameDead )
int seed, in_addr& addr, bool gameDead )
{
bool spotTaken = false;
bool alreadyHere = AlreadyHere( hid, seed, socket, &spotTaken );
@ -222,7 +222,7 @@ CookieRef::_Reconnect( int socket, HostID hid, int nPlayersH, int nPlayersS,
logf( XW_LOGINFO, "%s: dropping because already here",
__func__ );
} else {
pushReconnectEvent( socket, hid, nPlayersH, nPlayersS, seed );
pushReconnectEvent( socket, hid, nPlayersH, nPlayersS, seed, addr );
}
if ( gameDead ) {
pushGameDead( socket );
@ -242,13 +242,14 @@ CookieRef::_HandleAck( HostID hostID )
}
void
CookieRef::_PutMsg( HostID srcID, HostID destID, unsigned char* buf, int buflen )
CookieRef::_PutMsg( HostID srcID, in_addr& addr, HostID destID, unsigned char* buf, int buflen )
{
CRefEvent evt( XWE_PROXYMSG );
evt.u.fwd.src = srcID;
evt.u.fwd.dest = destID;
evt.u.fwd.buf = buf;
evt.u.fwd.buflen = buflen;
evt.u.fwd.addr = addr;
m_eventQueue.push_back( evt );
handleEvents();
@ -496,9 +497,10 @@ CookieRef::_CheckHeartbeats( time_t now )
#endif
void
CookieRef::_Forward( HostID src, HostID dest, unsigned char* buf, int buflen )
CookieRef::_Forward( HostID src, in_addr& addr, HostID dest, unsigned char* buf,
int buflen )
{
pushForwardEvent( src, dest, buf, buflen );
pushForwardEvent( src, addr, dest, buf, buflen );
handleEvents();
} /* Forward */
@ -511,7 +513,7 @@ CookieRef::_Remove( int socket )
void
CookieRef::pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
int seed )
int seed, in_addr& addr )
{
CRefEvent evt;
evt.type = XWE_DEVCONNECT;
@ -520,12 +522,13 @@ CookieRef::pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
evt.u.con.nPlayersH = nPlayersH;
evt.u.con.nPlayersS = nPlayersS;
evt.u.con.seed = seed;
evt.u.con.addr = addr;
m_eventQueue.push_back( evt );
} /* pushConnectEvent */
void
CookieRef::pushReconnectEvent( int socket, HostID srcID, int nPlayersH,
int nPlayersS, int seed )
int nPlayersS, int seed, in_addr& addr )
{
CRefEvent evt( XWE_RECONNECT );
evt.u.con.socket = socket;
@ -533,6 +536,7 @@ CookieRef::pushReconnectEvent( int socket, HostID srcID, int nPlayersH,
evt.u.con.nPlayersH = nPlayersH;
evt.u.con.nPlayersS = nPlayersS;
evt.u.con.seed = seed;
evt.u.con.addr = addr;
m_eventQueue.push_back( evt );
} /* pushReconnectEvent */
@ -557,7 +561,7 @@ CookieRef::pushHeartFailedEvent( int socket )
#endif
void
CookieRef::pushForwardEvent( HostID src, HostID dest,
CookieRef::pushForwardEvent( HostID src, in_addr& addr, HostID dest,
unsigned char* buf, int buflen )
{
logf( XW_LOGVERBOSE1, "pushForwardEvent: %d -> %d", src, dest );
@ -566,6 +570,7 @@ CookieRef::pushForwardEvent( HostID src, HostID dest,
evt.u.fwd.dest = dest;
evt.u.fwd.buf = buf;
evt.u.fwd.buflen = buflen;
evt.u.fwd.addr = addr;
m_eventQueue.push_back( evt );
}
@ -868,7 +873,8 @@ CookieRef::increasePlayerCounts( CRefEvent* evt, bool reconn, HostID* hidp )
}
evt->u.con.srcID = DBMgr::Get()->AddDevice( ConnName(), evt->u.con.srcID,
nPlayersH, seed, reconn );
nPlayersH, seed,
evt->u.con.addr, reconn );
HostID hostid = evt->u.con.srcID;
if ( NULL != hidp ) {
@ -1074,8 +1080,9 @@ CookieRef::forward_or_store( const CRefEvent* evt )
}
/* also note that we've heard from src recently */
#ifdef RELAY_HEARTBEAT
HostID src = evt->u.fwd.src;
DBMgr::Get()->RecordAddress( ConnName(), src, evt->u.fwd.addr );
#ifdef RELAY_HEARTBEAT
pushHeartbeatEvent( src, SocketForHost(src) );
#endif
} while ( 0 );

View file

@ -1,6 +1,6 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2005-2009 by Eric House (xwords@eehouse.org). All rights
* Copyright 2005-2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -120,17 +120,17 @@ class CookieRef {
static void Delete( const char* name );
bool _Connect( int socket, int nPlayersH, int nPlayersS, int seed,
bool seenSeed );
bool seenSeed, in_addr& addr );
bool _Reconnect( int socket, HostID srcID, int nPlayersH, int nPlayersS,
int seed, bool gameDead );
int seed, in_addr& addr, bool gameDead );
void _HandleAck( HostID hostID );
void _PutMsg( HostID srcID, HostID destID, unsigned char* buf, int buflen );
void _PutMsg( HostID srcID, in_addr& addr, HostID destID, unsigned char* buf, int buflen );
void _Disconnect(int socket, HostID hostID );
void _DeviceGone( HostID hostID, int seed );
void _Shutdown();
void _HandleHeartbeat( HostID id, int socket );
void _CheckHeartbeats( time_t now );
void _Forward( HostID src, HostID dest, unsigned char* buf, int buflen );
void _Forward( HostID src, in_addr& addr, HostID dest, unsigned char* buf, int buflen );
void _Remove( int socket );
void _CheckAllConnected();
void _CheckNotAcked( HostID hid );
@ -151,6 +151,7 @@ class CookieRef {
HostID dest;
unsigned char* buf;
int buflen;
in_addr addr;
} fwd;
struct {
int socket;
@ -158,6 +159,7 @@ class CookieRef {
int nPlayersS;
int seed;
HostID srcID;
in_addr addr;
} con;
struct {
HostID srcID;
@ -192,14 +194,14 @@ class CookieRef {
void send_msg( int socket, HostID id, XWRelayMsg msg, XWREASON why,
bool cascade );
void pushConnectEvent( int socket, int nPlayersH, int nPlayersS,
int seed );
int seed, in_addr& addr );
void pushReconnectEvent( int socket, HostID srcID,
int nPlayersH, int nPlayersS,
int seed );
int seed, in_addr& addr );
void pushHeartbeatEvent( HostID id, int socket );
void pushHeartFailedEvent( int socket );
void pushForwardEvent( HostID src, HostID dest, unsigned char* buf,
void pushForwardEvent( HostID src, in_addr& addr, HostID dest, unsigned char* buf,
int buflen );
void pushDestBadEvent();
void pushLastSocketGoneEvent();

View file

@ -1,7 +1,7 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2005-2009 by Eric House (xwords@eehouse.org). All rights
* Copyright 2005-2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -185,37 +185,38 @@ class SafeCref {
/* SafeCref( CookieRef* cref ); */
~SafeCref();
bool Forward( HostID src, HostID dest, unsigned char* buf, int buflen ) {
bool Forward( HostID src, in_addr& addr, HostID dest, unsigned char* buf, int buflen ) {
if ( IsValid() ) {
CookieRef* cref = m_cinfo->GetRef();
assert( 0 != cref->GetCid() );
cref->_Forward( src, dest, buf, buflen );
cref->_Forward( src, addr, dest, buf, buflen );
return true;
} else {
return false;
}
}
void PutMsg( HostID srcID, HostID destID, unsigned char* buf, int buflen ) {
void PutMsg( HostID srcID, in_addr& addr, HostID destID, unsigned char* buf,
int buflen ) {
if ( IsValid() ) {
CookieRef* cref = m_cinfo->GetRef();
assert( 0 != cref->GetCid() );
cref->_PutMsg( srcID, destID, buf, buflen );
cref->_PutMsg( srcID, addr, destID, buf, buflen );
}
}
bool Connect( int socket, int nPlayersH, int nPlayersS, int seed ) {
bool Connect( int socket, int nPlayersH, int nPlayersS, int seed, in_addr& addr ) {
if ( IsValid() ) {
CookieRef* cref = m_cinfo->GetRef();
assert( 0 != cref->GetCid() );
return cref->_Connect( socket, nPlayersH, nPlayersS, seed,
m_seenSeed );
m_seenSeed, addr );
} else {
return false;
}
}
bool Reconnect( int socket, HostID srcID, int nPlayersH, int nPlayersS,
int seed, XWREASON* errp ) {
int seed, in_addr& addr, XWREASON* errp ) {
bool success = false;
*errp = XWRELAY_ERROR_NONE;
if ( IsValid() ) {
@ -225,7 +226,7 @@ class SafeCref {
*errp = XWRELAY_ERROR_DEADGAME;
} else {
success = cref->_Reconnect( socket, srcID, nPlayersH,
nPlayersS, seed, m_dead );
nPlayersS, seed, addr, m_dead );
}
}
return success;

View file

@ -1,7 +1,8 @@
/* -*- compile-command: "make -k -j3"; -*- */
/*
* Copyright 2010 by Eric House (xwords@eehouse.org). All rights reserved.
* Copyright 2010-2012 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
@ -22,6 +23,9 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "dbmgr.h"
#include "mlock.h"
@ -71,8 +75,6 @@ DBMgr::DBMgr()
DBMgr::~DBMgr()
{
logf( XW_LOGINFO, "%s called", __func__ );
assert( s_instance == this );
s_instance = NULL;
}
@ -237,7 +239,7 @@ DBMgr::AllDevsAckd( const char* const connName )
HostID
DBMgr::AddDevice( const char* connName, HostID curID, int nToAdd,
unsigned short seed, bool ackd )
unsigned short seed, const in_addr& addr, bool ackd )
{
HostID newID = curID;
@ -253,10 +255,11 @@ DBMgr::AddDevice( const char* connName, HostID curID, int nToAdd,
assert( newID <= 4 );
const char* fmt = "UPDATE " GAMES_TABLE " SET nPerDevice[%d] = %d,"
" seeds[%d] = %d, mtimes[%d]='now', ack[%d]=\'%c\'"
" seeds[%d] = %d, addrs[%d] = \'%s\', mtimes[%d]='now', ack[%d]=\'%c\'"
" WHERE connName = '%s'";
char query[256];
snprintf( query, sizeof(query), fmt, newID, nToAdd, newID, seed, newID,
snprintf( query, sizeof(query), fmt, newID, nToAdd, newID, seed,
newID, inet_ntoa(addr), newID,
newID, ackd?'A':'a', connName );
logf( XW_LOGINFO, "%s: query: %s", __func__, query );
@ -426,6 +429,19 @@ DBMgr::RecordSent( const int* msgIDs, int nMsgIDs )
}
}
void
DBMgr::RecordAddress( const char* const connName, HostID hid, const in_addr& addr )
{
assert( hid >= 0 && hid <= 4 );
const char* fmt = "UPDATE " GAMES_TABLE " SET addrs[%d] = \'%s\'"
" WHERE connName = '%s'";
char query[256];
snprintf( query, sizeof(query), fmt, hid, inet_ntoa(addr), connName );
logf( XW_LOGINFO, "%s: query: %s", __func__, query );
execSql( query );
}
void
DBMgr::GetPlayerCounts( const char* const connName, int* nTotal, int* nHere )
{

View file

@ -1,7 +1,8 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2010 by Eric House (xwords@eehouse.org). All rights reserved.
* Copyright 2010 - 2012 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
@ -55,7 +56,7 @@ class DBMgr {
bool AllDevsAckd( const char* const connName );
HostID AddDevice( const char* const connName, HostID curID,
int nToAdd, unsigned short seed, bool unAckd );
int nToAdd, unsigned short seed, const in_addr& addr, bool unAckd );
void NoteAckd( const char* const connName, HostID id );
HostID HIDForSeed( const char* const connName, unsigned short seed );
bool RmDeviceByHid( const char* const connName, HostID id );
@ -65,6 +66,8 @@ class DBMgr {
void ClearCID( const char* connName );
void RecordSent( const char* const connName, HostID hid, int nBytes );
void RecordSent( const int* msgID, int nMsgIDs );
void RecordAddress( const char* const connName, HostID hid,
const in_addr& addr );
void GetPlayerCounts( const char* const connName, int* nTotal,
int* nHere );

View file

@ -1,7 +1,7 @@
/* -*- compile-command: "make -j3"; -*- */
/*
* Copyright 2005-2009 by Eric House (xwords@eehouse.org). All rights
* Copyright 2005 - 2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -106,18 +106,22 @@ XWThreadPool::Stop()
int ii;
for ( ii = 0; ii < m_nThreads; ++ii ) {
enqueue( 0, STYPE_UNKNOWN );
SockInfo si = { STYPE_UNKNOWN, {0} };
enqueue( 0, si );
}
interrupt_poll();
}
void
XWThreadPool::AddSocket( int socket, SockType stype )
XWThreadPool::AddSocket( int socket, SockType stype, in_addr& from )
{
{
RWWriteLock ml( &m_activeSocketsRWLock );
m_activeSockets.push_back( pair<int,SockType>(socket, stype) );
SockInfo si;
si.m_type = stype;
si.m_addr = from;
m_activeSockets.push_back( pair<int,SockInfo>(socket, si) );
}
interrupt_poll();
}
@ -129,7 +133,7 @@ XWThreadPool::RemoveSocket( int socket )
{
RWWriteLock ml( &m_activeSocketsRWLock );
vector< pair<int,SockType> >::iterator iter = m_activeSockets.begin();
vector< pair<int,SockInfo> >::iterator iter = m_activeSockets.begin();
while ( iter != m_activeSockets.end() ) {
if ( iter->first == socket ) {
m_activeSockets.erase( iter );
@ -173,11 +177,12 @@ void
XWThreadPool::EnqueueKill( int socket, const char* const why )
{
logf( XW_LOGINFO, "%s(%d) reason: %s", __func__, socket, why );
enqueue( socket, STYPE_UNKNOWN, Q_KILL );
SockInfo si = { STYPE_UNKNOWN, {0} };
enqueue( socket, si, Q_KILL );
}
bool
XWThreadPool::get_process_packet( int socket, SockType stype )
XWThreadPool::get_process_packet( int socket, SockType stype, in_addr& addr )
{
bool success = false;
short packetSize;
@ -189,10 +194,10 @@ XWThreadPool::get_process_packet( int socket, SockType stype )
EnqueueKill( socket, "bad packet" );
} else if ( STYPE_GAME == stype ) {
logf( XW_LOGINFO, "calling m_pFunc" );
success = (*m_pFunc)( buf, nRead, socket );
success = (*m_pFunc)( buf, nRead, socket, addr );
} else {
buf[nRead] = '\0';
handle_proxy_packet( buf, nRead, socket );
handle_proxy_packet( buf, nRead, socket, addr );
CloseSocket( socket );
}
return success;
@ -236,8 +241,8 @@ XWThreadPool::real_tpool_main()
pr.m_socket );
switch ( pr.m_act ) {
case Q_READ:
if ( get_process_packet( pr.m_socket, pr.m_type ) ) {
AddSocket( pr.m_socket, pr.m_type );
if ( get_process_packet( pr.m_socket, pr.m_info.m_type, pr.m_info.m_addr ) ) {
AddSocket( pr.m_socket, pr.m_info.m_type, pr.m_info.m_addr );
}
break;
case Q_KILL:
@ -273,7 +278,7 @@ XWThreadPool::real_listener()
int nSocketsAllocd = 1;
struct pollfd* fds = (pollfd*)calloc( nSocketsAllocd, sizeof(fds[0]) );
SockType* stypes = (SockType*)calloc( nSocketsAllocd, sizeof(stypes[0]) );
SockInfo* sinfos = (SockInfo*)calloc( nSocketsAllocd, sizeof(sinfos[0]) );
#ifdef LOG_POLL
char* log = (char*)malloc( 4 * nSocketsAllocd );
#endif
@ -289,7 +294,7 @@ XWThreadPool::real_listener()
if ( nSockets > nSocketsAllocd ) {
fds = (struct pollfd*)realloc( fds, nSockets * sizeof(fds[0]) );
stypes = (SockType*)realloc( stypes, nSockets * sizeof(stypes[0]) );
sinfos = (SockInfo*)realloc( sinfos, nSockets * sizeof(sinfos[0]) );
#ifdef LOG_POLL
log = (char*)realloc( log, nSockets * 4 );
#endif
@ -305,11 +310,11 @@ XWThreadPool::real_listener()
#endif
++curfd;
vector< pair<int,SockType> >::iterator iter;
vector< pair<int,SockInfo> >::iterator iter;
for ( iter = m_activeSockets.begin(); iter != m_activeSockets.end();
++iter ) {
fds[curfd].fd = iter->first;
stypes[curfd] = iter->second;
sinfos[curfd] = iter->second;
fds[curfd].events = flags;
#ifdef LOG_POLL
if ( logCapacity > logLen ) {
@ -369,7 +374,7 @@ XWThreadPool::real_listener()
}
if ( 0 != (fds[curfd].revents & (POLLIN | POLLPRI)) ) {
enqueue( socket, stypes[curfd] );
enqueue( socket, sinfos[curfd] );
} else {
logf( XW_LOGERROR, "odd revents: %x",
fds[curfd].revents );
@ -384,7 +389,7 @@ XWThreadPool::real_listener()
}
free( fds );
free( stypes );
free( sinfos );
#ifdef LOG_POLL
free( log );
#endif
@ -403,9 +408,9 @@ XWThreadPool::listener_main( void* closure )
}
void
XWThreadPool::enqueue( int socket, SockType stype, QAction act )
XWThreadPool::enqueue( int socket, SockInfo si, QAction act )
{
QueuePr pr = { act, socket, stype };
QueuePr pr = { act, socket, si };
MutexLock ml( &m_queueMutex );
m_queue.push_back( pr );

View file

@ -1,7 +1,8 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2005 by Eric House (xwords@eehouse.org). All rights reserved.
* Copyright 2005 - 2012 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
@ -36,9 +37,14 @@ class XWThreadPool {
public:
typedef enum { STYPE_UNKNOWN, STYPE_GAME, STYPE_PROXY } SockType;
typedef struct _SockInfo {
SockType m_type;
in_addr m_addr;
} SockInfo;
static XWThreadPool* GetTPool();
typedef bool (*packet_func)( unsigned char* buf, int bufLen, int socket );
typedef bool (*packet_func)( unsigned char* buf, int bufLen, int socket,
in_addr& addr );
typedef void (*kill_func)( int socket );
XWThreadPool();
@ -48,7 +54,7 @@ class XWThreadPool {
void Stop();
/* Add to set being listened on */
void AddSocket( int socket, SockType stype );
void AddSocket( int socket, SockType stype, in_addr& fromAddr );
/* remove from tpool altogether, and close */
void CloseSocket( int socket );
@ -56,18 +62,18 @@ class XWThreadPool {
private:
typedef enum { Q_READ, Q_KILL } QAction;
typedef struct { QAction m_act; int m_socket; SockType m_type; } QueuePr;
typedef struct { QAction m_act; int m_socket; SockInfo m_info; } QueuePr;
/* Remove from set being listened on */
bool RemoveSocket( int socket );
void enqueue( int socket, QAction act = Q_READ );
void enqueue( int socket, SockType stype, QAction act = Q_READ );
void enqueue( int socket, SockInfo si, QAction act = Q_READ );
void release_socket_locked( int socket );
void grab_elem_locked( QueuePr* qpp );
void print_in_use( void );
bool get_process_packet( int socket, SockType stype );
bool get_process_packet( int socket, SockType stype, in_addr& addr );
void interrupt_poll();
void* real_tpool_main();
@ -77,7 +83,7 @@ class XWThreadPool {
static void* listener_main( void* closure );
/* Sockets main thread listens on */
vector< pair<int,SockType> >m_activeSockets;
vector< pair<int,SockInfo> >m_activeSockets;
pthread_rwlock_t m_activeSocketsRWLock;
/* Sockets waiting for a thread to read 'em */

View file

@ -1,7 +1,7 @@
/* -*- compile-command: "make"; -*- */
/* -*- compile-command: "make -j3"; -*- */
/*
* Copyright 2005-2010 by Eric House (xwords@eehouse.org). All rights
* Copyright 2005 - 2012 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
@ -320,7 +320,7 @@ send_with_length_unsafe( int socket, unsigned char* buf, int bufLen )
* game?
*/
static bool
processConnect( unsigned char* bufp, int bufLen, int socket )
processConnect( unsigned char* bufp, int bufLen, int socket, in_addr& addr )
{
char cookie[MAX_INVITE_LEN+1];
unsigned char* end = bufp + bufLen;
@ -358,7 +358,7 @@ processConnect( unsigned char* bufp, int bufLen, int socket )
seed, langCode, wantsPublic, makePublic );
/* nPlayersT etc could be slots in SafeCref to avoid passing
here */
success = scr.Connect( socket, nPlayersH, nPlayersT, seed );
success = scr.Connect( socket, nPlayersH, nPlayersT, seed, addr );
} else {
err = XWRELAY_ERROR_BADPROTO;
}
@ -371,12 +371,12 @@ processConnect( unsigned char* bufp, int bufLen, int socket )
} /* processConnect */
static bool
processReconnect( unsigned char* bufp, int bufLen, int socket )
processReconnect( unsigned char* bufp, int bufLen, int socket, in_addr& addr )
{
unsigned char* end = bufp + bufLen;
bool success = false;
logf( XW_LOGINFO, "processReconnect" );
logf( XW_LOGINFO, "%s()", __func__ );
unsigned char flags = *bufp++;
XWREASON err = flagsOK( flags );
@ -405,7 +405,7 @@ processReconnect( unsigned char* bufp, int bufLen, int socket )
nPlayersT, gameSeed, langCode,
wantsPublic, makePublic );
success = scr.Reconnect( socket, srcID, nPlayersH, nPlayersT,
gameSeed, &err );
gameSeed, addr, &err );
if ( !success ) {
assert( err != XWRELAY_ERROR_NONE );
}
@ -488,7 +488,7 @@ GetNSpawns(void)
/* forward the message. Need only change the command after looking up the
* socket and it's ready to go. */
static bool
forwardMessage( unsigned char* buf, int buflen, int srcSocket )
forwardMessage( unsigned char* buf, int buflen, int srcSocket, in_addr& addr )
{
bool success = false;
unsigned char* bufp = buf + 1; /* skip cmd */
@ -504,17 +504,17 @@ forwardMessage( unsigned char* buf, int buflen, int srcSocket )
if ( COOKIE_ID_NONE == cookieID ) {
SafeCref scr( srcSocket );
success = scr.Forward( src, dest, buf, buflen );
success = scr.Forward( src, addr, dest, buf, buflen );
} else {
SafeCref scr( cookieID ); /* won't work if not allcon; will be 0 */
success = scr.Forward( src, dest, buf, buflen );
success = scr.Forward( src, addr, dest, buf, buflen );
}
}
return success;
} /* forwardMessage */
static bool
processMessage( unsigned char* buf, int bufLen, int socket )
processMessage( unsigned char* buf, int bufLen, int socket, in_addr& addr )
{
bool success = false; /* default is failure */
XWRELAY_Cmd cmd = *buf;
@ -523,10 +523,10 @@ processMessage( unsigned char* buf, int bufLen, int socket )
switch( cmd ) {
case XWRELAY_GAME_CONNECT:
success = processConnect( buf+1, bufLen-1, socket );
success = processConnect( buf+1, bufLen-1, socket, addr );
break;
case XWRELAY_GAME_RECONNECT:
success = processReconnect( buf+1, bufLen-1, socket );
success = processReconnect( buf+1, bufLen-1, socket, addr );
break;
case XWRELAY_ACK:
success = processAck( buf+1, bufLen-1, socket );
@ -540,7 +540,7 @@ processMessage( unsigned char* buf, int bufLen, int socket )
break;
#endif
case XWRELAY_MSG_TORELAY:
success = forwardMessage( buf, bufLen, socket );
success = forwardMessage( buf, bufLen, socket, addr );
break;
default:
logf( XW_LOGERROR, "%s bad: %d", __func__, cmd );
@ -748,10 +748,9 @@ pushMsgs( vector<unsigned char>& out, DBMgr* dbmgr, const char* connName,
}
static void
handleMsgsMsg( int sock, bool sendFull,
handleMsgsMsg( int sock, in_addr& addr, bool sendFull,
unsigned char* bufp, const unsigned char* end )
{
logf( XW_LOGINFO, "%s()", __func__ );
unsigned short nameCount;
int ii;
if ( getNetShort( &bufp, end, &nameCount ) ) {
@ -778,6 +777,8 @@ handleMsgsMsg( int sock, bool sendFull,
break;
}
dbmgr->RecordAddress( connName, hid, addr );
/* For each relayID, write the number of messages and then
each message (in the getmsg case) */
int msgCount = dbmgr->PendingMsgCount( connName, hid );
@ -848,7 +849,7 @@ log_hex( const unsigned char* memp, int len, const char* tag )
} // log_hex
static void
handleProxyMsgs( int sock, unsigned char* bufp, unsigned char* end )
handleProxyMsgs( int sock, in_addr& addr, unsigned char* bufp, unsigned char* end )
{
// log_hex( bufp, end-bufp, __func__ );
unsigned short nameCount;
@ -889,7 +890,7 @@ handleProxyMsgs( int sock, unsigned char* bufp, unsigned char* end )
&& getNetByte( &bufp, end, &dest ) ) {
assert( cmd == XWRELAY_MSG_TORELAY_NOCONN );
assert( hid == dest );
scr.PutMsg( src, dest, start, len );
scr.PutMsg( src, addr, dest, start, len );
bufp = start + len;
continue;
}
@ -903,7 +904,7 @@ handleProxyMsgs( int sock, unsigned char* bufp, unsigned char* end )
} // handleProxyMsgs
void
handle_proxy_packet( unsigned char* buf, int len, int sock )
handle_proxy_packet( unsigned char* buf, int len, int sock, in_addr& addr )
{
logf( XW_LOGINFO, "%s()", __func__ );
if ( len > 0 ) {
@ -935,12 +936,12 @@ handle_proxy_packet( unsigned char* buf, int len, int sock )
case PRX_HAS_MSGS:
case PRX_GET_MSGS:
if ( len >= 2 ) {
handleMsgsMsg( sock, PRX_GET_MSGS == cmd, bufp, end );
handleMsgsMsg( sock, addr, PRX_GET_MSGS == cmd, bufp, end );
}
break; /* PRX_HAS_MSGS */
case PRX_PUT_MSGS:
handleProxyMsgs( sock, bufp, end );
handleProxyMsgs( sock, addr, bufp, end );
break;
case PRX_DEVICE_GONE:
@ -1348,12 +1349,13 @@ main( int argc, char** argv )
enable_keepalive( newSock );
logf( XW_LOGINFO,
"accepting connection from %s on socket %d",
inet_ntoa(newaddr.sin_addr), newSock );
"%s: accepting connection from %s on socket %d",
__func__, inet_ntoa(newaddr.sin_addr), newSock );
tPool->AddSocket( newSock,
perGame ? XWThreadPool::STYPE_GAME
: XWThreadPool::STYPE_PROXY );
: XWThreadPool::STYPE_PROXY,
newaddr.sin_addr );
}
--retval;
}

View file

@ -56,6 +56,7 @@ cid integer
,nSent INTEGER DEFAULT 0
,ctime TIMESTAMP (0) DEFAULT CURRENT_TIMESTAMP
,mtimes TIMESTAMP(0)[]
,addrs INET[]
);
EOF

View file

@ -1,9 +1,29 @@
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2005 - 2012 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.
*/
#ifndef _XWRELAY_PRIV_H_
#define _XWRELAY_PRIV_H_
#include <time.h>
#include <netinet/in.h>
#include "lstnrmgr.h"
#include "xwrelay.h"
@ -30,7 +50,8 @@ int GetNSpawns(void);
int make_socket( unsigned long addr, unsigned short port );
int read_packet( int sock, unsigned char* buf, int buflen );
void handle_proxy_packet( unsigned char* buf, int bufLen, int socket );
void handle_proxy_packet( unsigned char* buf, int bufLen, int socket,
in_addr& addr );
const char* cmdToStr( XWRELAY_Cmd cmd );