From 72dd8f6b6a7ec159e46bcae7c652e70b312ebda5 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 4 Jan 2012 18:11:29 -0800 Subject: [PATCH 1/2] ignore debian build files --- xwords4/debian/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 xwords4/debian/.gitignore diff --git a/xwords4/debian/.gitignore b/xwords4/debian/.gitignore new file mode 100644 index 000000000..64a2389b0 --- /dev/null +++ b/xwords4/debian/.gitignore @@ -0,0 +1,2 @@ +*.ex + From caa40fa0233b9e110d049a8fcb19dcce29695f62 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 4 Jan 2012 18:14:12 -0800 Subject: [PATCH 2/2] store most recent IP address each device has come in on. Requires new column in db. Not really used yet but interesting to watch.... --- xwords4/relay/cref.cpp | 35 +++++++++++++++---------- xwords4/relay/cref.h | 18 +++++++------ xwords4/relay/crefmgr.h | 19 +++++++------- xwords4/relay/dbmgr.cpp | 28 +++++++++++++++----- xwords4/relay/dbmgr.h | 7 +++-- xwords4/relay/tpool.cpp | 43 +++++++++++++++++-------------- xwords4/relay/tpool.h | 20 ++++++++++----- xwords4/relay/xwrelay.cpp | 50 +++++++++++++++++++----------------- xwords4/relay/xwrelay.sh | 1 + xwords4/relay/xwrelay_priv.h | 23 ++++++++++++++++- 10 files changed, 154 insertions(+), 90 deletions(-) diff --git a/xwords4/relay/cref.cpp b/xwords4/relay/cref.cpp index bea704060..9e1ecb05f 100644 --- a/xwords4/relay/cref.cpp +++ b/xwords4/relay/cref.cpp @@ -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 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 ); diff --git a/xwords4/relay/cref.h b/xwords4/relay/cref.h index b382b66d3..65618fe40 100644 --- a/xwords4/relay/cref.h +++ b/xwords4/relay/cref.h @@ -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(); diff --git a/xwords4/relay/crefmgr.h b/xwords4/relay/crefmgr.h index a15e0b748..8596a1d5c 100644 --- a/xwords4/relay/crefmgr.h +++ b/xwords4/relay/crefmgr.h @@ -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; diff --git a/xwords4/relay/dbmgr.cpp b/xwords4/relay/dbmgr.cpp index 679b8934b..38dab2781 100644 --- a/xwords4/relay/dbmgr.cpp +++ b/xwords4/relay/dbmgr.cpp @@ -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 #include #include +#include +#include +#include #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 ) { diff --git a/xwords4/relay/dbmgr.h b/xwords4/relay/dbmgr.h index 34f013beb..8aad5bc88 100644 --- a/xwords4/relay/dbmgr.h +++ b/xwords4/relay/dbmgr.h @@ -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 ); diff --git a/xwords4/relay/tpool.cpp b/xwords4/relay/tpool.cpp index d5010e908..282fb8593 100644 --- a/xwords4/relay/tpool.cpp +++ b/xwords4/relay/tpool.cpp @@ -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(socket, stype) ); + SockInfo si; + si.m_type = stype; + si.m_addr = from; + m_activeSockets.push_back( pair(socket, si) ); } interrupt_poll(); } @@ -129,7 +133,7 @@ XWThreadPool::RemoveSocket( int socket ) { RWWriteLock ml( &m_activeSocketsRWLock ); - vector< pair >::iterator iter = m_activeSockets.begin(); + vector< pair >::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 >::iterator iter; + vector< pair >::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 ); diff --git a/xwords4/relay/tpool.h b/xwords4/relay/tpool.h index 353b32d58..483900800 100644 --- a/xwords4/relay/tpool.h +++ b/xwords4/relay/tpool.h @@ -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 >m_activeSockets; + vector< pair >m_activeSockets; pthread_rwlock_t m_activeSocketsRWLock; /* Sockets waiting for a thread to read 'em */ diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index 2b920a14f..77a943a90 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -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& 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; } diff --git a/xwords4/relay/xwrelay.sh b/xwords4/relay/xwrelay.sh index 99ac6a211..f58caf835 100755 --- a/xwords4/relay/xwrelay.sh +++ b/xwords4/relay/xwrelay.sh @@ -56,6 +56,7 @@ cid integer ,nSent INTEGER DEFAULT 0 ,ctime TIMESTAMP (0) DEFAULT CURRENT_TIMESTAMP ,mtimes TIMESTAMP(0)[] +,addrs INET[] ); EOF diff --git a/xwords4/relay/xwrelay_priv.h b/xwords4/relay/xwrelay_priv.h index 5226609a2..27c5a088a 100644 --- a/xwords4/relay/xwrelay_priv.h +++ b/xwords4/relay/xwrelay_priv.h @@ -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 +#include #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 );