#include <ArServerBase.h>
Inheritance diagram for ArServerBase:
Data request callbacks are added to an ArServerBase object by calling addData().
This class takes care of locking in its own function calls so you don't need to worry about locking and unlocking the class before you do things.
The counterpart of this class for clients is ArClientBase.
You can require user names and passwords for making connections to the server, so each user has a set of permissions for different command groups. To do this, load configuration from a userInfo file with loadUserInfo(). You can log the user info (and what commands users have) with logUserInfo(). You can log the command groups with logCommandGroups() or logCommandGroupsToFile(). For a description of the file see ArServerUserInfo. There is also an example in ArNetworking/examples/serverDemo.userInfo
.
In addition to the user and password requirement you can set a server "key" (a special string of text) required (in addition to user and password) to access the server with setServerKey(), though this is ONLY used if user and password information is requied (so that older clients can connect if there's no user and password information required).
The way that the passwords are transmitted across the network is this: Upon connection the server sends a randomly generated (for that connection) string of text to the client which we'll call the passwordKey. The client then combines the serverKey (a string which must be known to connect to the server at all), the password, and the passwordKey (that string that is generated uniquely for each connection) and comes up with an md5 of that string and sends that md5 value across the line. The server then compares the md5 from the client with the md5 generated with the correct information on the server... if they match the password is good, otherwise it rejects the connection. This is NOT perfect security but should be much better then plaintext. If you care about perfect security then use an ssh tunnel with something like PUTTY from the machine the client is on to the machine the server is on with an openssh server set up (this'll likely even work in windows with cygwin) and set up a firewall on the machine the server is on that disallows port the server port connection from outside and only allows ssh from outside (and get a book or three and read those).
This class now handles identifiers for the ArServerClients... all server bases will let a client set a self identifier string, and a here goal... those may be used by any server. Messages can be sent to just server clients that match that message (so that its easier to send messages to people who sent commands).
Master servers (the main connection server base on the central server) can also give each connection an id number (with identGetConnectionID). Things that then connect to the other server bases on a master server (slave servers) should then set their ConnectionID (with identSetConnectionID) so that things can relate the different connections together.
Public Member Functions | |
void | addClientRemovedCallback (ArFunctor1< ArServerClient * > *functor) |
Add a callback to be invoked when a client has been removed (but before it is deleted). | |
void | addCycleCallback (ArFunctor *functor) |
Add a callback to be called at every cycle. | |
bool | addData (const char *name, const char *description, ArFunctor2< ArServerClient *, ArNetPacket * > *functor, const char *argumentDescription, const char *returnDescription, const char *commandGroup=NULL, const char *dataFlags=NULL) |
Adds a callback to be called when requests for some data are recieved. | |
bool | addDataAdvanced (const char *name, const char *description, ArFunctor2< ArServerClient *, ArNetPacket * > *functor, const char *argumentDescription, const char *returnDescription, const char *commandGroup=NULL, const char *dataFlags=NULL, unsigned int commandNumber=0, ArFunctor2< long, unsigned int > *requestChangedFunctor=NULL, ArFunctor2< ArServerClient *, ArNetPacket * > *requestOnceFunctor=NULL) |
Adds a callback for requests in a more advanced manner, for internal use. | |
bool | addIdleSingleShotCallback (ArFunctor *functor) |
Adds an idle callback to be called once next time the robot is idle. | |
bool | allowingIdlePackets (void) |
Gets if we're allowing idle packets. | |
ArServerBase (bool addAriaExitCB=true, const char *serverName="", bool addBackupTimeoutToConfig=true, const char *backupTimeoutName="RobotToClientTimeoutInMins", const char *backupTimeoutDesc="The amount of time the central server can go without sending a packet to the robot successfully (when there are packets to send). A number less than 0 means this won't happen. The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", bool masterServer=false, bool slaveServer=false, bool logPasswordFailureVerbosely=false, bool allowSlowPackets=true, bool allowIdlePackets=true) | |
Constructor. | |
bool | broadcastPacketTcp (ArNetPacket *packet, const char *name) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketTcpByCommand (ArNetPacket *packet, unsigned int command) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketTcpByCommandWithExclusion (ArNetPacket *packet, unsigned int command, ArServerClient *excludeClient, bool match=false, ArServerClientIdentifier identifier=ArServerClientIdentifier(), bool matchConnectionID=false) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketTcpToMatching (ArNetPacket *packet, const char *name, ArServerClientIdentifier identifier, bool matchConnectionID=false) |
Broadcasts packets to any client wanting this data that matches the ID. | |
bool | broadcastPacketTcpWithExclusion (ArNetPacket *packet, const char *name, ArServerClient *excludeClient, bool match=false, ArServerClientIdentifier identifier=ArServerClientIdentifier(), bool matchConnectionID=false) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketUdp (ArNetPacket *packet, const char *name) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketUdpByCommand (ArNetPacket *packet, unsigned int command) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketUdpByCommandWithExclusion (ArNetPacket *packet, unsigned int command, ArServerClient *excludeClient, bool match=false, ArServerClientIdentifier identifier=ArServerClientIdentifier(), bool matchConnectionID=false) |
Broadcasts packets to any client wanting this data. | |
bool | broadcastPacketUdpToMatching (ArNetPacket *packet, const char *name, ArServerClientIdentifier identifier, bool matchConnectionID) |
Broadcasts packets to any client wanting this data that matches. | |
bool | broadcastPacketUdpWithExclusion (ArNetPacket *packet, const char *name, ArServerClient *excludeClient, bool match=false, ArServerClientIdentifier identifier=ArServerClientIdentifier(), bool matchConnectionID=false) |
Broadcasts packets to any client wanting this data. | |
void | close (void) |
Closes the server. | |
void | closeConnectionID (ArTypes::UByte4 idNum) |
Closes connection with a given connection ID. | |
bool | dataHasFlag (const char *name, const char *dataFlag) |
Returns if a command has a data flag. | |
bool | dataHasFlagByCommand (unsigned int command, const char *dataFlag) |
Returns if a command has a data flag by command number. | |
unsigned int | findCommandFromName (const char *command) |
Gets the number of a command. | |
bool | getDebugLogging (void) |
Gets if this is using debug logging. | |
long | getFrequency (unsigned int command, bool internalCall=false) |
Gets the frequncy a command is requested (mostly internal). | |
int | getMostClients (void) |
Gets the most clients we've had connected. | |
int | getNumClients (void) |
Gets the number of clients connected. | |
const char * | getOpenOnIP (void) |
Gets the IP we're opening on (or NULL if there's none). | |
unsigned int | getTcpPort (void) |
Gets the tcp port we're using. | |
unsigned int | getUdpPort (void) |
Gets the udp port we're using. | |
const ArServerUserInfo * | getUserInfo (void) const |
Gets the user info we're using (mostly internal for switching). | |
bool | hasIdleCallbacks (void) |
Internal, Sees if we have any idle callbacks we are waiting to process. | |
bool | hasIdlePackets (void) |
Internal, Sees if we have any idle packets we are waiting to process. | |
bool | hasSlowPackets (void) |
Internal, Sees if we have any slow packets we are waiting to process. | |
bool | idleProcessingPending (void) |
Sees if we have any idle processing pending (idle packets or callbacks). | |
bool | loadUserInfo (const char *fileName, const char *baseDirectory="") |
Loads up a set of usernames/passwords/permissions from a file. | |
void | logCommandGroups (void) |
Logs the groups and commands in those groups. | |
void | logCommandGroupsToFile (const char *fileName) |
Logs the groups and commands in those groups to a file. | |
void | logConnections (const char *prefix="") |
Logs the connections. | |
void | logGroupDescriptions (void) |
Logs the command group names and descriptions. | |
void | logGroupDescriptionsToFile (const char *fileName) |
Logs the command group names and descriptions to a file. | |
void | logTracking (bool terse=true) |
Logs the tracking on each client (how many packets and bytes were sent). | |
void | logUserInfo (void) |
Logs the users and their groups. | |
void | loopOnce (void) |
Runs the server loop once. | |
ArServerClient * | makeNewServerClientFromSocket (ArSocket *socket, bool doNotReject) |
Makes a new serverclient from this socket (for switching, needs no password since this was an outgoing connection to a trusted server). | |
bool | open (unsigned int port, const char *openOnIP=NULL, bool tcpOnly=false) |
Opens the server to accept new client connections. | |
void | processPacket (ArNetPacket *packet, struct sockaddr_in *sin) |
Processes udp packets. | |
void | rejectSinceUsingCentralServer (const char *centralServerIPString) |
Tells the server to reject connectings because we're usinga central server. | |
void | remClientRemovedCallback (ArFunctor1< ArServerClient * > *functor) |
Remove the callback invoked when a client has been removed. | |
void | remCycleCallback (ArFunctor *functor) |
Remove a callback to be called at every cycle. | |
void | resetTracking (void) |
Clears the tracking on all the clients (resets counters). | |
virtual void | run (void) |
Runs the server in this thread. | |
virtual void | runAsync (void) |
Runs the server in its own thread. | |
virtual void * | runThread (void *arg) |
bool | sendUdp (ArNetPacket *packet, struct sockaddr_in *sin) |
Sends Udp packets. | |
void | setAdditionalDataFlags (const char *additionalDataFlags) |
Sets the data flags to add in addition to those passed in. | |
void | setBackupTimeout (double timeoutInMins) |
Sets the backup timeout. | |
void | setDebugLogging (bool debugLogging=false) |
Sets debug logging. | |
void | setGroupDescription (const char *GrpName, const char *GrpDesc) |
Logs the command group names and command group descriptions for those names. | |
void | setServerKey (const char *serverKey) |
Sets a 'key' needed to access the server through any account. | |
void | setUserInfo (const ArServerUserInfo *userInfo) |
Sets the user info we'll use (mostly internal for switching). | |
virtual | ~ArServerBase () |
Destructor. | |
Protected Member Functions | |
void | acceptTcpSockets (void) |
accepts new sockets and moves them into the client list | |
ArServerClient * | finishAcceptingSocket (ArSocket *socket, bool skipPassword=false, bool doNotReject=false) |
Internal function for server/client switching. | |
void | identGetConnectionID (ArServerClient *client, ArNetPacket *packet) |
The command get the ConnectionID of this server client connection. | |
void | identSetConnectionID (ArServerClient *client, ArNetPacket *packet) |
The command set the ConnectionID of this server client connection. | |
void | identSetHereGoal (ArServerClient *client, ArNetPacket *packet) |
The command set the here goal of this server client connection. | |
void | identSetSelfIdentifier (ArServerClient *client, ArNetPacket *packet) |
The command set the self identifier of this server client connection. | |
void | netIdleProcessingPending (ArServerClient *client, ArNetPacket *packet) |
bool | processFile (void) |
void | slowIdleCallback (void) |
Protected Attributes | |
ArSocket | myAcceptingSocket |
std::string | myAdditionalDataFlags |
std::list< ArServerClient * > | myAddList |
ArMutex | myAddListMutex |
bool | myAllowIdlePackets |
bool | myAllowSlowPackets |
ArFunctorC< ArServerBase > | myAriaExitCB |
double | myBackupTimeout |
std::list< ArFunctor1< ArServerClient * > * > | myClientRemovedCallbacks |
std::list< ArServerClient * > | myClients |
ArMutex | myClientsMutex |
ArTypes::UByte4 | myConnectionNumber |
std::list< ArFunctor * > | myCycleCallbacks |
ArMutex | myCycleCallbacksMutex |
std::map< unsigned int, ArServerData * > | myDataMap |
ArMutex | myDataMutex |
bool | myDebugLogging |
ArRetFunctor2C< long, ArServerBase, unsigned int, bool > | myGetFrequencyCB |
std::map< std::string, std::string > | myGroupDescription |
our mapping of the group names | |
bool | myHaveIdleCallbacks |
bool | myHaveIdlePackets |
bool | myHaveSlowPackets |
ArFunctor2C< ArServerBase, ArServerClient *, ArNetPacket * > | myIdentGetConnectionIDCB |
ArFunctor2C< ArServerBase, ArServerClient *, ArNetPacket * > | myIdentSetConnectionIDCB |
ArFunctor2C< ArServerBase, ArServerClient *, ArNetPacket * > | myIdentSetHereGoalCB |
ArFunctor2C< ArServerBase, ArServerClient *, ArNetPacket * > | myIdentSetSelfIdentifierCB |
std::list< ArFunctor * > | myIdleCallbacks |
ArMutex | myIdleCallbacksMutex |
ArFunctor2C< ArServerBase, ArServerClient *, ArNetPacket * > | myIdleProcessingPendingCB |
bool | myLastIdleProcessingPending |
bool | myLogPasswordFailureVerbosely |
std::string | myLogPrefix |
unsigned int | myLoopMSecs |
int | myMostClients |
unsigned int | myNextDataNumber |
int | myNumClients |
bool | myOpened |
std::string | myOpenOnIP |
ArRetFunctorC< bool, ArServerBase > | myProcessFileCB |
ArMutex | myProcessingSlowIdleMutex |
ArFunctor2C< ArServerBase, ArNetPacket *, struct sockaddr_in * > | myProcessPacketCB |
int | myRejecting |
std::string | myRejectingString |
std::set< ArServerClient * > | myRemoveSet |
ArMutex | myRemoveSetMutex |
ArRetFunctor2C< bool, ArServerBase, ArNetPacket *, struct sockaddr_in * > | mySendUdpCB |
std::string | myServerKey |
std::string | myServerName |
SlowIdleThread * | mySlowIdleThread |
bool | myTcpOnly |
unsigned int | myTcpPort |
ArSocket | myTcpSocket |
unsigned int | myUdpPort |
ArNetPacketReceiverUdp | myUdpReceiver |
ArSocket | myUdpSocket |
const ArServerUserInfo * | myUserInfo |
ArLog::LogLevel | myVerboseLogLevel |
Friends | |
class | ArServerBase::SlowIdleThread |
void ArServerBase::netIdleProcessingPending | ( | ArServerClient * | client, | |
ArNetPacket * | packet | |||
) | [protected] |
callback for our slow idle thread, which is down below... The command that returns if there is idle processing to do