Pass protocol version code with connect request, and return error if

it isn't what relay can handle.  Report error to user.
This commit is contained in:
ehouse 2005-07-06 01:36:52 +00:00
parent 77374484f8
commit 3b53363e16
7 changed files with 81 additions and 22 deletions

View file

@ -691,13 +691,16 @@ relayPreProcess( CommsCtxt* comms, XWStreamCtxt* stream, XWHostID* senderID )
cookieID, srcID, destID );
/* If these values don't check out, drop it */
consumed = cookieID != comms->cookieID
&& destID != comms->myHostID;
|| destID != comms->myHostID;
if ( consumed ) {
XP_LOGF( "rejecting data message" );
} else {
*senderID = srcID;
}
break;
case XWRELAY_CONNECTDENIED:
util_userError( comms->util, ERR_RELAY_ERROR );
/* fallthru */
default:
consumed = XP_TRUE; /* drop it */
XP_LOGF( "dropping relay msg with cmd %d", (XP_U16)cmd );
@ -979,6 +982,7 @@ send_via_relay( CommsCtxt* comms, XWRELAY_Cmd cmd, XWHostID destID,
}
break;
case XWRELAY_CONNECT:
stream_putU8( tmpStream, XWRELAY_PROTO_VERSION );
stringToStream( tmpStream, addr.u.ip_relay.cookie );
stream_putU16( tmpStream, comms->myHostID );
XP_LOGF( "writing cookieID of %ld", comms->cookieID );

View file

@ -50,7 +50,9 @@ typedef enum {
/* ERR_CANT_ENGINE_MID_MOVE, */
/* ERR_NOT_YOUR_TURN_TO_TRADE, */
/* ERR_NOT_YOUR_TURN_TO_MOVE, */
ERR_CANT_UNDO_TILEASSIGN
ERR_CANT_UNDO_TILEASSIGN,
ERR_RELAY_ERROR
} UtilErrID;
typedef enum {

View file

@ -164,6 +164,11 @@ linux_getErrString( UtilErrID id )
case ERR_CANT_UNDO_TILEASSIGN:
message = "Tile assignment can't be undone.";
break;
case ERR_RELAY_ERROR:
message = "Problem communicating with the relay. Maybe it's "
"overloaded or is expecting a newer version of Crosswords";
break;
default:
message = "<unrecognized error code reported>";
}

View file

@ -493,17 +493,9 @@ static void
send_with_length( int socket, unsigned char* buf, int bufLen )
{
SocketWriteLock slock( socket );
int ok = 0;
unsigned short len = htons( bufLen );
ssize_t nSent = send( socket, &len, 2, 0 );
if ( nSent == 2 ) {
nSent = send( socket, buf, bufLen, 0 );
if ( nSent == bufLen ) {
logf( "sent %d bytes on socket %d", nSent, socket );
ok = 1;
}
}
if ( !ok ) {
if ( !send_with_length_unsafe( socket, buf, bufLen ) ) {
/* ok that the slock above is still in scope */
killSocket( socket, "couldn't send" );
}
}

View file

@ -128,6 +128,42 @@ readCookie( unsigned char** bufp, const unsigned char* end,
return 0;
} /* readCookie */
static int
flagsOK( unsigned char flags )
{
return flags == XWRELAY_PROTO_VERSION;
} /* flagsOK */
static void
denyConnection( int socket )
{
unsigned char buf[2];
buf[0] = XWRELAY_CONNECTDENIED;
buf[1] = XWRELAY_ERROR_BADPROTO;
send_with_length_unsafe( socket, buf, sizeof(buf) );
}
/* No mutex here. Caller better be ensuring no other thread can access this
* socket. */
int
send_with_length_unsafe( int socket, unsigned char* buf, int bufLen )
{
int ok = 0;
unsigned short len = htons( bufLen );
ssize_t nSent = send( socket, &len, 2, 0 );
if ( nSent == 2 ) {
nSent = send( socket, buf, bufLen, 0 );
if ( nSent == bufLen ) {
logf( "sent %d bytes on socket %d", nSent, socket );
ok = 1;
}
}
return ok;
} /* send_with_length_unsafe */
/* A CONNECT message from a device gives us the hostID and socket we'll
* associate with one participant in a relayed session. We'll store this
* information with the cookie where other participants can find it when they
@ -147,19 +183,24 @@ processConnect( unsigned char* bufp, int bufLen, int socket )
logf( "processConnect" );
if ( readCookie( &bufp, end, cookie ) ) {
unsigned char flags = *bufp++;
if ( flagsOK( flags ) ) {
if ( readCookie( &bufp, end, cookie ) ) {
HostID srcID;
CookieID cookieID;
HostID srcID;
CookieID cookieID;
if ( bufp + sizeof(srcID) + sizeof(cookieID) == end ) {
srcID = getNetShort( &bufp );
cookieID = getNetLong( &bufp );
if ( bufp + sizeof(srcID) + sizeof(cookieID) == end ) {
srcID = getNetShort( &bufp );
cookieID = getNetLong( &bufp );
CookieRef* cref = get_make_cookieRef( cookie, cookieID );
assert( cref != NULL );
cref->Connect( socket, srcID );
CookieRef* cref = get_make_cookieRef( cookie, cookieID );
assert( cref != NULL );
cref->Connect( socket, srcID );
}
}
} else {
denyConnection( socket );
}
} /* processConnect */

View file

@ -38,6 +38,9 @@ enum { XWRELAY_NONE /* 0 is an illegal value */
/* Sent from relay to device in response to XWRELAY_CONNECT.
Format: heartbeat_seconds: 2; connectionID: 2; */
/* The relay says go away. Format: reason code: 1 */
, XWRELAY_CONNECTDENIED
, XWRELAY_HEARTBEAT
/* Sent in either direction. Format: cookieID: 2; srcID: 2 */
@ -60,4 +63,14 @@ typedef unsigned char XWRELAY_Cmd;
#define MAX_COOKIE_LEN 15
#define MAX_MSG_LEN 256 /* 100 is more like it */
#define XWRELAY_PROTO_VERSION 0x01
/* Errors passed with denied */
enum {
XWRELAY_ERROR_NONE
,XWRELAY_ERROR_BADPROTO
,XWRELAY_ERROR_RELAYBUSY
,XWRELAY_ERROR_COOKIEINUSE
};
#endif

View file

@ -12,6 +12,8 @@ void logf( const char* format, ... );
void killSocket( int socket, char* why );
int send_with_length_unsafe( int socket, unsigned char* buf, int bufLen );
time_t now();
#endif