Merge branch 'relay_proxy' of ssh://xwords.git.sourceforge.net/gitroot/xwords/xwords into relay_proxy

This commit is contained in:
Eric House 2010-09-22 05:46:10 -07:00
commit 82825365d4
8 changed files with 113 additions and 38 deletions

View file

@ -55,7 +55,7 @@ xwrelay: $(OBJ)
rq: rq.c
clean:
rm -f xwrelay $(OBJ)
rm -f xwrelay $(OBJ) rq
tags:
etags *.cpp *.h

View file

@ -225,6 +225,32 @@ DBMgr::ClearCIDs( void )
execSql( "UPDATE " TABLE_NAME " set cid = null" );
}
void
DBMgr::PublicRooms( int lang, int nPlayers, int* nNames, string& names )
{
int ii;
int nTuples;
const char* fmt = "SELECT room, nTotal-nJoined FROM " TABLE_NAME
" WHERE ispublic = TRUE AND lang = %d AND ntotal =% d";
char query[256];
snprintf( query, sizeof(query), fmt, lang, nPlayers );
logf( XW_LOGINFO, "%s: query: %s", __func__, query );
MutexLock ml( &m_dbMutex );
PGresult* result = PQexec( m_pgconn, query );
nTuples = PQntuples( result );
for ( ii = 0; ii < nTuples; ++ii ) {
names.append( PQgetvalue( result, ii, 0 ) );
names.append( "/" );
names.append( PQgetvalue( result, ii, 1 ) );
}
PQclear( result );
*nNames = nTuples;
}
void
DBMgr::execSql( const char* query )
{

View file

@ -21,9 +21,13 @@
#ifndef _DBMGR_H_
#define _DBMGR_H_
#include <string>
#include "xwrelay.h"
#include <libpq-fe.h>
using namespace std;
class DBMgr {
public:
static DBMgr* Get();
@ -46,6 +50,12 @@ class DBMgr {
void AddCID( const char* connName, CookieID cid );
void ClearCID( const char* connName );
/* Return list of roomName/playersStillWanted for open public games
matching this language and total game size. Will probably want to cache
lists locally and only update them every few seconds to avoid to many
queries.*/
void PublicRooms( int lang, int nPlayers, int* nNames, string& names );
private:
DBMgr();
void execSql( const char* query ); /* no-results query */

View file

@ -38,6 +38,8 @@
# define DEFAULT_HOST "localhost"
#endif
#define MAX_CONN_NAMES 32
/*
* Query:
* list of all public games by language and number of players
@ -52,10 +54,11 @@ usage( const char * const argv0 )
fprintf( stderr, "usage: %s \\\n", argv0 );
fprintf( stderr, "\t[-p <port>] # (default %d)\\\n", DEFAULT_PORT );
fprintf( stderr, "\t[-a <host>] # (default: %s)\\\n", DEFAULT_HOST );
fprintf( stderr, "\t-r # list open public rooms\\\n" );
fprintf( stderr, "\t -r # list open public rooms\\\n" );
fprintf( stderr, "\t[-l <n>] # language for rooms "
"(1=English default)\\\n" );
fprintf( stderr, "\t[-n <n>] # number of players (1 default)\\\n" );
fprintf( stderr, "\t[-n <n>] # number of players (2 default)\\\n" );
fprintf( stderr, "\t[-m <connName:devid> # list msg count\\\n" );
exit( 1 );
}
@ -63,14 +66,14 @@ static void
do_rooms( int sockfd, int lang, int nPlayers )
{
unsigned char msg[] = { 0, /* protocol */
PRX_PUBROOMS,
PRX_PUB_ROOMS,
lang,
nPlayers };
unsigned short len = htons( sizeof(msg) );
write( sockfd, &len, sizeof(len) );
write( sockfd, msg, sizeof(msg) );
fprintf( stderr, "Waiting for response...." );
fprintf( stderr, "Waiting for response....\n" );
ssize_t nRead = recv( sockfd, &len,
sizeof(len), MSG_WAITALL );
assert( nRead == sizeof(len) );
@ -89,22 +92,47 @@ do_rooms( int sockfd, int lang, int nPlayers )
char* saveptr;
for ( ii = 0; ii < nRooms; ++ii ) {
char* str = strtok_r( ptr, "\n", &saveptr );
fprintf( stdout, "%s", str );
fprintf( stdout, "%s\n", str );
ptr = NULL;
}
}
static void
do_msgs( int sockfd, const char** connNames, int nConnNames )
{
unsigned short len, netlen;
int ii;
for ( len = 0, ii = 0; ii < nConnNames; ++ii ) {
len += 1 + strlen( connNames[ii] );
}
unsigned char hdr[] = { 0, PRX_HAS_MSGS };
unsigned short netNConnNames = htons( nConnNames );
netlen = sizeof(hdr) + sizeof( netNConnNames ) + len;
netlen = htons( netlen );
write( sockfd, &netlen, sizeof(netlen) );
write( sockfd, &hdr, sizeof(hdr) );
write( sockfd, &netNConnNames, sizeof(netNConnNames) );
for ( len = 0, ii = 0; ii < nConnNames; ++ii ) {
write( sockfd, connNames[ii], strlen(connNames[ii]) );
write( sockfd, "\n", 1 );
}
} /* do_msgs */
int
main( int argc, char * const argv[] )
{
int port = DEFAULT_PORT;
int lang = 1;
int nPlayers = 1;
int nPlayers = 2;
bool doRooms = false;
bool doMgs = false;
const char* host = DEFAULT_HOST;
char const* connNames[MAX_CONN_NAMES];
int nConnNames = 0;
for ( ; ; ) {
int opt = getopt( argc, argv, "a:p:rl:n:" );
int opt = getopt( argc, argv, "a:p:rl:n:m:" );
if ( opt < 0 ) {
break;
}
@ -115,6 +143,11 @@ main( int argc, char * const argv[] )
case 'l':
lang = atoi(optarg);
break;
case 'm':
assert( nConnNames < MAX_CONN_NAMES - 1 );
connNames[nConnNames++] = optarg;
doMgs = true;
break;
case 'n':
nPlayers = atoi(optarg);
break;
@ -151,8 +184,9 @@ main( int argc, char * const argv[] )
if ( doRooms ) {
do_rooms( sockfd, lang, nPlayers );
} else {
usage( argv[0] );
}
if ( doMgs ) {
do_msgs( sockfd, connNames, nConnNames );
}
close( sockfd );

View file

@ -181,28 +181,13 @@ XWThreadPool::get_process_packet( int socket )
short packetSize;
assert( sizeof(packetSize) == 2 );
ssize_t nRead = recv( socket, &packetSize,
sizeof(packetSize), MSG_WAITALL );
if ( nRead != 2 ) {
EnqueueKill( socket, "nRead != 2" );
unsigned char buf[MAX_MSG_LEN];
int nRead = read_packet( socket, buf, sizeof(buf) );
if ( nRead < 0 ) {
EnqueueKill( socket, "bad packet" );
} else {
packetSize = ntohs( packetSize );
if ( packetSize < 0 || packetSize > MAX_MSG_LEN ) {
EnqueueKill( socket, "packetSize wrong" );
} else {
unsigned char buf[MAX_MSG_LEN];
nRead = recv( socket, buf, packetSize, MSG_WAITALL );
if ( nRead != packetSize ) {
EnqueueKill( socket, "nRead != packetSize" );
} else {
logf( XW_LOGINFO, "read %d bytes", nRead );
logf( XW_LOGINFO, "calling m_pFunc" );
success = (*m_pFunc)( buf, packetSize, socket );
}
}
logf( XW_LOGINFO, "calling m_pFunc" );
success = (*m_pFunc)( buf, nRead, socket );
}
return success;
} /* get_process_packet */

View file

@ -74,6 +74,7 @@
#include "timermgr.h"
#include "permid.h"
#include "lstnrmgr.h"
#include "dbmgr.h"
static int s_nSpawns = 0;
#define MAX_PROXY_LEN 64
@ -645,18 +646,20 @@ handlePipe( int sig )
logf( XW_LOGINFO, "%s", __func__ );
}
bool
int
read_packet( int sock, unsigned char* buf, int buflen )
{
bool result = false;
int result = -1;
ssize_t nread;
unsigned short msgLen;
nread = recv( sock, &msgLen, sizeof(msgLen), MSG_WAITALL );
if ( nread == sizeof(msgLen) ) {
msgLen = ntohs( msgLen );
if ( msgLen >= buflen ) {
if ( msgLen <= buflen ) {
nread = recv( sock, buf, msgLen, MSG_WAITALL );
result = nread == msgLen;
if ( nread == msgLen ) {
result = nread;
}
}
}
return result;
@ -676,8 +679,22 @@ handle_proxy_tproc( void* closure )
switch( cmd ) {
case PRX_NONE:
break;
case PRX_PUBROOMS:
logf( XW_LOGINFO, "%s: PRX_PUBROOMS", __func__ );
case PRX_PUB_ROOMS:
if ( len >= 4 ) {
int lang = *bufp++;
int nPlayers = *bufp++;
string names;
int nNames;
DBMgr::Get()->PublicRooms( lang, nPlayers, &nNames, names );
unsigned short netshort = htons( names.size()
+ sizeof(unsigned short) );
write( sock, &netshort, sizeof(netshort) );
netshort = htons( (unsigned short)nNames );
write( sock, &netshort, sizeof(netshort) );
write( sock, names.c_str(), names.size() );
}
break;
case PRX_HAS_MSGS:
break;
}
}

View file

@ -147,7 +147,8 @@ XWREASON
typedef
#endif
enum { PRX_NONE /* 0 is an illegal value */
,PRX_PUBROOMS
,PRX_PUB_ROOMS /* list all public rooms for lang/nPlayers */
,PRX_HAS_MSGS /* return message counts for connName/devid array */
}
#ifndef CANT_DO_TYPEDEF
XWPRXYCMD

View file

@ -27,6 +27,8 @@ int GetNSpawns(void);
int make_socket( unsigned long addr, unsigned short port );
int read_packet( int sock, unsigned char* buf, int buflen );
const char* cmdToStr( XWRELAY_Cmd cmd );
extern class ListenerMgr g_listeners;