diff --git a/xwords4/relay/crefmgr.cpp b/xwords4/relay/crefmgr.cpp index 766d50d73..2e5e225a2 100644 --- a/xwords4/relay/crefmgr.cpp +++ b/xwords4/relay/crefmgr.cpp @@ -240,7 +240,7 @@ CRefMgr::GetStats( CrefMgrInfo& mgrInfo ) if ( 0 == m_ports.length() ) { RelayConfigs* cfg = RelayConfigs::GetConfigs(); vector ints; - if ( cfg->GetValueFor( "PORTS", ints ) ) { + if ( cfg->GetValueFor( "GAME_PORTS", ints ) ) { vector::const_iterator iter; for ( iter = ints.begin(); ; ) { char buf[8]; diff --git a/xwords4/relay/lstnrmgr.cpp b/xwords4/relay/lstnrmgr.cpp index bbfa9623c..81dfb155b 100644 --- a/xwords4/relay/lstnrmgr.cpp +++ b/xwords4/relay/lstnrmgr.cpp @@ -29,11 +29,11 @@ #include "mlock.h" bool -ListenerMgr::AddListener( int port ) +ListenerMgr::AddListener( int port, bool perGame ) { logf( XW_LOGINFO, "%s(%d)", __func__, port ); MutexLock ml( &m_mutex ); - return addOne( port ); + return addOne( port, perGame ); } void @@ -43,9 +43,9 @@ ListenerMgr::SetAll( const vector* ivp ) MutexLock ml( &m_mutex ); vector have; - map::iterator iter2 = m_socks_to_ports.begin(); + map >::iterator iter2 = m_socks_to_ports.begin(); while ( iter2 != m_socks_to_ports.end() ) { - have.push_back(iter2->second); + have.push_back(iter2->second.first); ++iter2; } std::sort(have.begin(), have.end()); @@ -61,7 +61,7 @@ ListenerMgr::SetAll( const vector* ivp ) assert( iHave <= have.size() && iWant <= want.size() ); while( (iWant < want.size()) && ((iHave == have.size() || want[iWant] < have[iHave])) ) { - addOne( want[iWant] ); + addOne( want[iWant], true ); ++iWant; } while ( (iHave < have.size()) @@ -90,7 +90,7 @@ ListenerMgr::RemoveAll() { MutexLock ml( &m_mutex ); for ( ; ; ) { - map::const_iterator iter = m_socks_to_ports.begin(); + map >::const_iterator iter = m_socks_to_ports.begin(); if ( iter == m_socks_to_ports.end() ) { break; } @@ -102,7 +102,7 @@ void ListenerMgr::AddToFDSet( fd_set* rfds ) { MutexLock ml( &m_mutex ); - map::const_iterator iter = m_socks_to_ports.begin(); + map >::const_iterator iter = m_socks_to_ports.begin(); while ( iter != m_socks_to_ports.end() ) { FD_SET( iter->first, rfds ); ++iter; @@ -114,7 +114,7 @@ ListenerMgr::GetHighest() { int highest = 0; MutexLock ml( &m_mutex ); - map::const_iterator iter = m_socks_to_ports.begin(); + map >::const_iterator iter = m_socks_to_ports.begin(); while ( iter != m_socks_to_ports.end() ) { if ( iter->first > highest ) { highest = iter->first; @@ -136,7 +136,7 @@ ListenerMgr::removeSocket( int sock ) { /* Assumption: we have the mutex! */ logf( XW_LOGINFO, "%s(%d)", __func__, sock ); - map::iterator iter = m_socks_to_ports.find( sock ); + map >::iterator iter = m_socks_to_ports.find( sock ); assert( iter != m_socks_to_ports.end() ); m_socks_to_ports.erase(iter); close(sock); @@ -147,9 +147,9 @@ ListenerMgr::removePort( int port ) { /* Assumption: we have the mutex! */ logf( XW_LOGINFO, "%s(%d)", __func__, port ); - map::iterator iter = m_socks_to_ports.begin(); + map >::iterator iter = m_socks_to_ports.begin(); while ( iter != m_socks_to_ports.end() ) { - if ( iter->second == port ) { + if ( iter->second.first == port ) { int sock = iter->first; close(sock); m_socks_to_ports.erase(iter); @@ -161,7 +161,7 @@ ListenerMgr::removePort( int port ) } bool -ListenerMgr::addOne( int port ) +ListenerMgr::addOne( int port, bool perGame ) { logf( XW_LOGINFO, "%s(%d)", __func__, port ); /* Assumption: we have the mutex! */ @@ -170,7 +170,8 @@ ListenerMgr::addOne( int port ) int sock = make_socket( INADDR_ANY, port ); success = sock != -1; if ( success ) { - m_socks_to_ports.insert( pair(sock, port) ); + pairentry(port, perGame); + m_socks_to_ports.insert( pair >(sock, entry ) ); } return success; } @@ -180,9 +181,9 @@ ListenerMgr::portInUse( int port ) { /* Assumption: we have the mutex! */ bool found = false; - map::const_iterator iter = m_socks_to_ports.begin(); + map >::const_iterator iter = m_socks_to_ports.begin(); while ( iter != m_socks_to_ports.end() ) { - if ( iter->second == port ) { + if ( iter->second.first == port ) { found = true; break; } @@ -193,10 +194,19 @@ ListenerMgr::portInUse( int port ) int ListenersIter::next() +{ + return this->next( NULL ); +} + +int +ListenersIter::next( bool* perGame ) { int result = -1; if ( m_iter != m_lm->m_socks_to_ports.end() ) { - result = m_fds? m_iter->first : m_iter->second; + result = m_fds? m_iter->first : m_iter->second.first; + if ( NULL != perGame ) { + *perGame = m_iter->second.second; + } ++m_iter; } /* logf( XW_LOGINFO, "%s=>%d", __func__, result ); */ diff --git a/xwords4/relay/lstnrmgr.h b/xwords4/relay/lstnrmgr.h index 8960a28e3..67622e8de 100644 --- a/xwords4/relay/lstnrmgr.h +++ b/xwords4/relay/lstnrmgr.h @@ -34,7 +34,7 @@ class ListenerMgr { public: void RemoveAll(); /* void RemoveListener( int listener ); */ - bool AddListener( int port ); + bool AddListener( int port, bool perGame ); void SetAll( const vector* iv ); /* replace current set with this new one */ void AddToFDSet( fd_set* rfds ); int GetHighest(); @@ -43,10 +43,10 @@ class ListenerMgr { private: void removeSocket( int sock ); void removePort( int port ); - bool addOne( int listener ); + bool addOne( int listener, bool perGame ); bool portInUse( int port ); - map m_socks_to_ports; + map< int,pair > m_socks_to_ports; pthread_mutex_t m_mutex; friend class ListenersIter; }; @@ -65,10 +65,11 @@ class ListenersIter { } int next(); + int next( bool* perGame ); private: bool m_fds; - map::const_iterator m_iter; + map< int,pair >::const_iterator m_iter; ListenerMgr* m_lm; }; diff --git a/xwords4/relay/xwrelay.conf_tmplate b/xwords4/relay/xwrelay.conf_tmplate index a39ef739b..9ae5e071d 100644 --- a/xwords4/relay/xwrelay.conf_tmplate +++ b/xwords4/relay/xwrelay.conf_tmplate @@ -15,9 +15,11 @@ HEARTBEAT=60 # How many worker threads in the thread pool? Default is five. NTHREADS=3 -# What ports do we listen on for incoming connections? -PORTS=10999 +# What ports do we listen on for per-game incoming connections? +GAME_PORTS=10999 #PORTS=10997,10998,10999 +# What ports do we listen on for per-device incoming connections? +DEVICE_PORTS=10998 # And the control port is? CTLPORT=11000 diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index 8f9ebac40..6f7d3d5ae 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -814,18 +814,19 @@ main( int argc, char** argv ) (void)sigaction( SIGPIPE, &sact, NULL ); if ( port != 0 ) { - g_listeners.AddListener( port ); + g_listeners.AddListener( port, true ); } - vector ints; - if ( !cfg->GetValueFor( "PORTS", ints ) ) { + vector ints_game; + if ( !cfg->GetValueFor( "GAME_PORTS", ints_game ) ) { exit( 1 ); } - vector::const_iterator iter; - for ( iter = ints.begin(); iter != ints.end(); ++iter ) { - int port = *iter; + vector::const_iterator iter_game; + for ( iter_game = ints_game.begin(); iter_game != ints_game.end(); + ++iter_game ) { + int port = *iter_game; if ( !g_listeners.PortInUse( port ) ) { - if ( !g_listeners.AddListener( port ) ) { + if ( !g_listeners.AddListener( port, true ) ) { exit( 1 ); } } else { @@ -833,6 +834,22 @@ main( int argc, char** argv ) } } + vector ints_device; + if ( cfg->GetValueFor( "DEVICE_PORTS", ints_device ) ) { + + vector::const_iterator iter; + for ( iter = ints_device.begin(); iter != ints_device.end(); ++iter ) { + int port = *iter; + if ( !g_listeners.PortInUse( port ) ) { + if ( !g_listeners.AddListener( port, false ) ) { + exit( 1 ); + } + } else { + logf( XW_LOGERROR, "port %d was in use", port ); + } + } + } + g_control = make_socket( INADDR_LOOPBACK, ctrlport ); if ( g_control == -1 ) { exit( 1 ); @@ -895,7 +912,8 @@ main( int argc, char** argv ) } else { ListenersIter iter(&g_listeners, true); while ( retval > 0 ) { - int listener = iter.next(); + bool perGame; + int listener = iter.next( &perGame ); if ( listener < 0 ) { break; } @@ -906,11 +924,16 @@ main( int argc, char** argv ) int newSock = accept( listener, (sockaddr*)&newaddr, &siz ); - logf( XW_LOGINFO, - "accepting connection from %s on socket %d", - inet_ntoa(newaddr.sin_addr), newSock ); + if ( perGame ) { + logf( XW_LOGINFO, + "accepting connection from %s on socket %d", + inet_ntoa(newaddr.sin_addr), newSock ); + + tPool->AddSocket( newSock ); + } else { + logf( XW_LOGERROR, "can't handle device socket yet" ); + } - tPool->AddSocket( newSock ); --retval; } }