mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-17 18:12:01 +01:00
Merge branch 'relay_proxy' of ssh://xwords.git.sourceforge.net/gitroot/xwords/xwords into relay_proxy
This commit is contained in:
commit
82825365d4
8 changed files with 113 additions and 38 deletions
|
@ -55,7 +55,7 @@ xwrelay: $(OBJ)
|
||||||
rq: rq.c
|
rq: rq.c
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f xwrelay $(OBJ)
|
rm -f xwrelay $(OBJ) rq
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
etags *.cpp *.h
|
etags *.cpp *.h
|
||||||
|
|
|
@ -225,6 +225,32 @@ DBMgr::ClearCIDs( void )
|
||||||
execSql( "UPDATE " TABLE_NAME " set cid = null" );
|
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
|
void
|
||||||
DBMgr::execSql( const char* query )
|
DBMgr::execSql( const char* query )
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,13 @@
|
||||||
#ifndef _DBMGR_H_
|
#ifndef _DBMGR_H_
|
||||||
#define _DBMGR_H_
|
#define _DBMGR_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "xwrelay.h"
|
#include "xwrelay.h"
|
||||||
#include <libpq-fe.h>
|
#include <libpq-fe.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class DBMgr {
|
class DBMgr {
|
||||||
public:
|
public:
|
||||||
static DBMgr* Get();
|
static DBMgr* Get();
|
||||||
|
@ -46,6 +50,12 @@ class DBMgr {
|
||||||
void AddCID( const char* connName, CookieID cid );
|
void AddCID( const char* connName, CookieID cid );
|
||||||
void ClearCID( const char* connName );
|
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:
|
private:
|
||||||
DBMgr();
|
DBMgr();
|
||||||
void execSql( const char* query ); /* no-results query */
|
void execSql( const char* query ); /* no-results query */
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
# define DEFAULT_HOST "localhost"
|
# define DEFAULT_HOST "localhost"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_CONN_NAMES 32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Query:
|
* Query:
|
||||||
* list of all public games by language and number of players
|
* 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, "usage: %s \\\n", argv0 );
|
||||||
fprintf( stderr, "\t[-p <port>] # (default %d)\\\n", DEFAULT_PORT );
|
fprintf( stderr, "\t[-p <port>] # (default %d)\\\n", DEFAULT_PORT );
|
||||||
fprintf( stderr, "\t[-a <host>] # (default: %s)\\\n", DEFAULT_HOST );
|
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 "
|
fprintf( stderr, "\t[-l <n>] # language for rooms "
|
||||||
"(1=English default)\\\n" );
|
"(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 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +66,14 @@ static void
|
||||||
do_rooms( int sockfd, int lang, int nPlayers )
|
do_rooms( int sockfd, int lang, int nPlayers )
|
||||||
{
|
{
|
||||||
unsigned char msg[] = { 0, /* protocol */
|
unsigned char msg[] = { 0, /* protocol */
|
||||||
PRX_PUBROOMS,
|
PRX_PUB_ROOMS,
|
||||||
lang,
|
lang,
|
||||||
nPlayers };
|
nPlayers };
|
||||||
unsigned short len = htons( sizeof(msg) );
|
unsigned short len = htons( sizeof(msg) );
|
||||||
write( sockfd, &len, sizeof(len) );
|
write( sockfd, &len, sizeof(len) );
|
||||||
write( sockfd, msg, sizeof(msg) );
|
write( sockfd, msg, sizeof(msg) );
|
||||||
|
|
||||||
fprintf( stderr, "Waiting for response...." );
|
fprintf( stderr, "Waiting for response....\n" );
|
||||||
ssize_t nRead = recv( sockfd, &len,
|
ssize_t nRead = recv( sockfd, &len,
|
||||||
sizeof(len), MSG_WAITALL );
|
sizeof(len), MSG_WAITALL );
|
||||||
assert( nRead == sizeof(len) );
|
assert( nRead == sizeof(len) );
|
||||||
|
@ -89,22 +92,47 @@ do_rooms( int sockfd, int lang, int nPlayers )
|
||||||
char* saveptr;
|
char* saveptr;
|
||||||
for ( ii = 0; ii < nRooms; ++ii ) {
|
for ( ii = 0; ii < nRooms; ++ii ) {
|
||||||
char* str = strtok_r( ptr, "\n", &saveptr );
|
char* str = strtok_r( ptr, "\n", &saveptr );
|
||||||
fprintf( stdout, "%s", str );
|
fprintf( stdout, "%s\n", str );
|
||||||
ptr = NULL;
|
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
|
int
|
||||||
main( int argc, char * const argv[] )
|
main( int argc, char * const argv[] )
|
||||||
{
|
{
|
||||||
int port = DEFAULT_PORT;
|
int port = DEFAULT_PORT;
|
||||||
int lang = 1;
|
int lang = 1;
|
||||||
int nPlayers = 1;
|
int nPlayers = 2;
|
||||||
bool doRooms = false;
|
bool doRooms = false;
|
||||||
|
bool doMgs = false;
|
||||||
const char* host = DEFAULT_HOST;
|
const char* host = DEFAULT_HOST;
|
||||||
|
char const* connNames[MAX_CONN_NAMES];
|
||||||
|
int nConnNames = 0;
|
||||||
|
|
||||||
for ( ; ; ) {
|
for ( ; ; ) {
|
||||||
int opt = getopt( argc, argv, "a:p:rl:n:" );
|
int opt = getopt( argc, argv, "a:p:rl:n:m:" );
|
||||||
if ( opt < 0 ) {
|
if ( opt < 0 ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -115,6 +143,11 @@ main( int argc, char * const argv[] )
|
||||||
case 'l':
|
case 'l':
|
||||||
lang = atoi(optarg);
|
lang = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
assert( nConnNames < MAX_CONN_NAMES - 1 );
|
||||||
|
connNames[nConnNames++] = optarg;
|
||||||
|
doMgs = true;
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
nPlayers = atoi(optarg);
|
nPlayers = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -151,8 +184,9 @@ main( int argc, char * const argv[] )
|
||||||
|
|
||||||
if ( doRooms ) {
|
if ( doRooms ) {
|
||||||
do_rooms( sockfd, lang, nPlayers );
|
do_rooms( sockfd, lang, nPlayers );
|
||||||
} else {
|
}
|
||||||
usage( argv[0] );
|
if ( doMgs ) {
|
||||||
|
do_msgs( sockfd, connNames, nConnNames );
|
||||||
}
|
}
|
||||||
|
|
||||||
close( sockfd );
|
close( sockfd );
|
||||||
|
|
|
@ -181,28 +181,13 @@ XWThreadPool::get_process_packet( int socket )
|
||||||
short packetSize;
|
short packetSize;
|
||||||
assert( sizeof(packetSize) == 2 );
|
assert( sizeof(packetSize) == 2 );
|
||||||
|
|
||||||
ssize_t nRead = recv( socket, &packetSize,
|
unsigned char buf[MAX_MSG_LEN];
|
||||||
sizeof(packetSize), MSG_WAITALL );
|
int nRead = read_packet( socket, buf, sizeof(buf) );
|
||||||
if ( nRead != 2 ) {
|
if ( nRead < 0 ) {
|
||||||
EnqueueKill( socket, "nRead != 2" );
|
EnqueueKill( socket, "bad packet" );
|
||||||
} else {
|
} else {
|
||||||
packetSize = ntohs( packetSize );
|
logf( XW_LOGINFO, "calling m_pFunc" );
|
||||||
|
success = (*m_pFunc)( buf, nRead, socket );
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
} /* get_process_packet */
|
} /* get_process_packet */
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
#include "timermgr.h"
|
#include "timermgr.h"
|
||||||
#include "permid.h"
|
#include "permid.h"
|
||||||
#include "lstnrmgr.h"
|
#include "lstnrmgr.h"
|
||||||
|
#include "dbmgr.h"
|
||||||
|
|
||||||
static int s_nSpawns = 0;
|
static int s_nSpawns = 0;
|
||||||
#define MAX_PROXY_LEN 64
|
#define MAX_PROXY_LEN 64
|
||||||
|
@ -645,18 +646,20 @@ handlePipe( int sig )
|
||||||
logf( XW_LOGINFO, "%s", __func__ );
|
logf( XW_LOGINFO, "%s", __func__ );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
read_packet( int sock, unsigned char* buf, int buflen )
|
read_packet( int sock, unsigned char* buf, int buflen )
|
||||||
{
|
{
|
||||||
bool result = false;
|
int result = -1;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
unsigned short msgLen;
|
unsigned short msgLen;
|
||||||
nread = recv( sock, &msgLen, sizeof(msgLen), MSG_WAITALL );
|
nread = recv( sock, &msgLen, sizeof(msgLen), MSG_WAITALL );
|
||||||
if ( nread == sizeof(msgLen) ) {
|
if ( nread == sizeof(msgLen) ) {
|
||||||
msgLen = ntohs( msgLen );
|
msgLen = ntohs( msgLen );
|
||||||
if ( msgLen >= buflen ) {
|
if ( msgLen <= buflen ) {
|
||||||
nread = recv( sock, buf, msgLen, MSG_WAITALL );
|
nread = recv( sock, buf, msgLen, MSG_WAITALL );
|
||||||
result = nread == msgLen;
|
if ( nread == msgLen ) {
|
||||||
|
result = nread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -676,8 +679,22 @@ handle_proxy_tproc( void* closure )
|
||||||
switch( cmd ) {
|
switch( cmd ) {
|
||||||
case PRX_NONE:
|
case PRX_NONE:
|
||||||
break;
|
break;
|
||||||
case PRX_PUBROOMS:
|
case PRX_PUB_ROOMS:
|
||||||
logf( XW_LOGINFO, "%s: PRX_PUBROOMS", __func__ );
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,8 @@ XWREASON
|
||||||
typedef
|
typedef
|
||||||
#endif
|
#endif
|
||||||
enum { PRX_NONE /* 0 is an illegal value */
|
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
|
#ifndef CANT_DO_TYPEDEF
|
||||||
XWPRXYCMD
|
XWPRXYCMD
|
||||||
|
|
|
@ -27,6 +27,8 @@ int GetNSpawns(void);
|
||||||
|
|
||||||
int make_socket( unsigned long addr, unsigned short port );
|
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 );
|
const char* cmdToStr( XWRELAY_Cmd cmd );
|
||||||
|
|
||||||
extern class ListenerMgr g_listeners;
|
extern class ListenerMgr g_listeners;
|
||||||
|
|
Loading…
Reference in a new issue