# SocketServer.cc

Go to the documentation of this file.

    00001 // ----------------------------------------------------------------------------
    00002 // CERTI - HLA RunTime Infrastructure
    00003 // Copyright (C) 2002-2005  ONERA
    00004 //
    00005 // This file is part of CERTI-libCERTI
    00006 //
    00007 // CERTI-libCERTI is free software ; you can redistribute it and/or
    00008 // modify it under the terms of the GNU Lesser General Public License
    00009 // as published by the Free Software Foundation ; either version 2 of
    00010 // the License, or (at your option) any later version.
    00011 //
    00012 // CERTI-libCERTI is distributed in the hope that it will be useful, but
    00013 // WITHOUT ANY WARRANTY ; without even the implied warranty of
    00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    00015 // Lesser General Public License for more details.
    00016 //
    00017 // You should have received a copy of the GNU Lesser General Public
    00018 // License along with this program ; if not, write to the Free Software
    00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
    00020 // USA
    00021 //
    00022 // $Id: SocketServer.cc,v 3.18 2008/10/13 10:06:48 erk Exp $
    00023 // ----------------------------------------------------------------------------
    00024
    00025
    00026 #include "SocketServer.hh"
    00027 #include "PrettyDebug.hh"
    00028
    00029 using std::list ;
    00030
    00031 namespace certi {
    00032 static PrettyDebug G("GENDOC",__FILE__);
    00033 // ----------------------------------------------------------------------------
    00038 int
    00039 SocketServer::addToFDSet(fd_set *select_fdset)
    00040 {
    00041     int fd_max = 0 ;
    00042
    00043     list<SocketTuple *>::iterator i ;
    00044     for (i = begin(); i != end(); i++) {
    00045         if ((*i)->ReliableLink != NULL) {
    00046         int fd = (*i)->ReliableLink->returnSocket();
    00047             FD_SET(fd, select_fdset);
    00048         fd_max = fd > fd_max ? fd : fd_max ;
    00049     }
    00050     }
    00051     return fd_max ;
    00052 }
    00053
    00054 // ----------------------------------------------------------------------------
    00060 void
    00061 SocketServer::checkMessage(long socket_number, NetworkMessage *message) const
    00062     throw (SecurityError)
    00063 {
    00064     // G.Out(pdGendoc,"enter SocketServer::checkMessage");
    00065
    00066     if ((message->federation == 0) && (message->federate == 0))
    00067         {
    00068         // G.Out(pdGendoc,"exit  SocketServer::checkMessage on return");
    00069         return ;
    00070         }
    00071
    00072     Socket *socket ;
    00073     try {
    00074         socket = getSocketLink(message->federation,
    00075                                message->federate);
    00076     }
    00077     catch (Exception &e) {
    00078         // BUG: Should put a line in the Audit.
    00079         throw SecurityError("Message has a unknown origin.");
    00080     }
    00081
    00082     if (socket->returnSocket() != socket_number) {
    00083         // BUG: Should put a line in the Audit.
    00084         throw SecurityError("Message has a forged origin.");
    00085     }
    00086     // G.Out(pdGendoc,"exit  SocketServer::checkMessage");
    00087 }
    00088
    00089 // ----------------------------------------------------------------------------
    00098 void
    00099 SocketServer::close(long socket,
    00100                     Handle &federation_referenced,
    00101                     FederateHandle &federate_referenced)
    00102     throw (RTIinternalError)
    00103 {
    00104     federation_referenced = 0 ;
    00105     federate_referenced = 0 ;
    00106
    00107     // It may throw RTIinternalError.
    00108     SocketTuple *tuple = getWithSocket(socket);
    00109
    00110     federation_referenced = tuple->Federation ;
    00111     federate_referenced = tuple->Federate ;
    00112
    00113     // If the Tuple had no references, remove it, else just delete the socket.
    00114     // Also, if no federate (no Join)
    00115     if (tuple->Federation == 0 && tuple->Federate != 0) {
    00116         list<SocketTuple *>::iterator i ;
    00117         list<SocketTuple *>::iterator tmp ;
    00118         for (i = begin(); i != end(); i++) {
    00119             if (((*i)->ReliableLink != NULL) &&
    00120                 ((*i)->ReliableLink->returnSocket() == socket)) {
    00121                 delete (*i);
    00122                 i= erase(i); // i is dereferenced.
    00123                 //tmp = erase(i); // i is dereferenced.
    00124                 //i = tmp-- ; // loop will increment i ;
    00125             }
    00126         }
    00127     }
    00128     else {
    00129         tuple->ReliableLink->close();
    00130         tuple->BestEffortLink->close();
    00131
    00132         delete tuple->ReliableLink ;
    00133         delete tuple->BestEffortLink ;
    00134
    00135         tuple->ReliableLink = NULL ;
    00136         tuple->BestEffortLink = NULL ;
    00137     }
    00138 }
    00139
    00140 // ----------------------------------------------------------------------------
    00142 SocketServer::SocketServer(SocketTCP *tcp_socket,
    00143                            SocketUDP *udp_socket, int /* the_port */)
    00144     : list<SocketTuple *>()
    00145 {
    00146     if (tcp_socket == NULL)
    00147         throw RTIinternalError("");
    00148
    00149     ServerSocketTCP = tcp_socket ;
    00150     ServerSocketUDP = udp_socket ;
    00151 }
    00152
    00153 // ----------------------------------------------------------------------------
    00155 SocketServer::~SocketServer()
    00156 {
    00157     // Deleting remaining tuples.
    00158     while (!list<SocketTuple *>::empty()) {
    00159         delete front();
    00160         pop_front();
    00161     }
    00162 }
    00163
    00164 // ----------------------------------------------------------------------------
    00166 SocketTuple::SocketTuple(Socket *tcp_link)
    00167     : Federation(0), Federate(0)
    00168 {
    00169     if (tcp_link != NULL)
    00170         ReliableLink = (SocketTCP *)tcp_link ;
    00171     else
    00172         throw RTIinternalError("Null socket");
    00173
    00174     BestEffortLink = new SocketUDP();
    00175 }
    00176
    00177 // ----------------------------------------------------------------------------
    00179 SocketTuple::~SocketTuple()
    00180 {
    00181     if (ReliableLink != NULL) {
    00182         ReliableLink->close();
    00183         delete ReliableLink ;
    00184         ReliableLink = NULL ;
    00185     }
    00186     if (BestEffortLink != NULL) {
    00187         BestEffortLink->close();
    00188         delete BestEffortLink ;
    00189         BestEffortLink = NULL ;
    00190     }
    00191 }
    00192
    00193 // ----------------------------------------------------------------------------
    00197 Socket *
    00198 SocketServer::getActiveSocket(fd_set *select_fdset) const
    00199 {
    00200     list<SocketTuple *>::const_iterator i ;
    00201     for (i = begin(); i != end(); i++) {
    00202         if (((*i)->ReliableLink != NULL) &&
    00203             (FD_ISSET((*i)->ReliableLink->returnSocket(), select_fdset)))
    00204             return (*i)->ReliableLink ;
    00205     }
    00206
    00207     return NULL ;
    00208 }
    00209
    00210 // ----------------------------------------------------------------------------
    00222 Socket*
    00223 SocketServer::getSocketLink(Handle the_federation,
    00224                             FederateHandle the_federate,
    00225                             TransportType the_type) const
    00226     throw (FederateNotExecutionMember, RTIinternalError)
    00227 {
    00228     // G.Out(pdGendoc,"enter SocketServer::getSocketLink");
    00229     // It may throw FederateNotExecutionMember
    00230     SocketTuple *tuple = getWithReferences(the_federation, the_federate);
    00231
    00232     if (the_type == RELIABLE) {
    00233         if (tuple->ReliableLink == 0)
    00234             {
    00235             return NULL ;
    00236             }
    00237             //throw RTIinternalError("Reference to a killed Federate.");
    00238         return tuple->ReliableLink ;
    00239     }
    00240     else {
    00241         if (tuple->BestEffortLink == 0)
    00242             {
    00243             return NULL ;
    00244             }
    00245             //throw RTIinternalError("Reference to a killed Federate.");
    00246         return tuple->BestEffortLink ;
    00247     }
    00248     // G.Out(pdGendoc,"exit  SocketServer::getSocketLink without return");
    00249 }
    00250
    00251 // ----------------------------------------------------------------------------
    00253 SocketTuple *
    00254 SocketServer::getWithReferences(Handle the_federation,
    00255                                 FederateHandle the_federate) const
    00256     throw (FederateNotExecutionMember)
    00257 {
    00258     list<SocketTuple *>::const_iterator i ;
    00259     for (i = begin(); i != end(); i++) {
    00260         if (((*i)->Federation == the_federation) &&
    00261             ((*i)->Federate == the_federate))
    00262             return (*i);
    00263     }
    00264
    00265     throw FederateNotExecutionMember("");
    00266 }
    00267
    00268 // ----------------------------------------------------------------------------
    00270 SocketTuple *
    00271 SocketServer::getWithSocket(long socket_descriptor) const
    00272     throw (RTIinternalError)
    00273 {
    00274     list<SocketTuple *>::const_iterator i ;
    00275     for (i = begin(); i != end(); i++) {
    00276         if (((*i)->ReliableLink != NULL) &&
    00277             ((*i)->ReliableLink->returnSocket() == socket_descriptor))
    00278             return (*i);
    00279         if (((*i)->BestEffortLink != NULL) &&
    00280             ((*i)->BestEffortLink->returnSocket() == socket_descriptor))
    00281             return (*i);
    00282     }
    00283
    00284     throw RTIinternalError("Socket not found.");
    00285 }
    00286
    00287 // ----------------------------------------------------------------------------
    00292 void
    00293 SocketServer::open()
    00294     throw (RTIinternalError)
    00295 {
    00296 #ifdef WITH_GSSAPI
    00297     SecureTCPSocket *newLink = new SecureTCPSocket();
    00298 #else
    00299     SocketTCP *newLink = new SocketTCP();
    00300 #endif
    00301
    00302     if (newLink == NULL)
    00303         throw RTIinternalError("Could not allocate new socket.");
    00304
    00305     newLink->accept(ServerSocketTCP);
    00306
    00307     SocketTuple *newTuple = new SocketTuple(newLink);
    00308
    00309     if (newTuple == NULL)
    00310         throw RTIinternalError("Could not allocate new tuple.");
    00311
    00312     push_front(newTuple);
    00313 }
    00314
    00315 // ----------------------------------------------------------------------------
    00322 void
    00323 SocketServer::setReferences(long socket,
    00324                             Handle federation_reference,
    00325                             FederateHandle federate_reference,
    00326                             unsigned long address,
    00327                             unsigned int port)
    00328     throw (RTIinternalError)
    00329 {
    00330     // It may throw RTIinternalError if not found.
    00331     SocketTuple *tuple = getWithSocket(socket);
    00332
    00333     if ((tuple->Federation != 0) || (tuple->Federate != 0))
    00334         // References have already been set once.
    00335         throw RTIinternalError("Socket References have already been set.");
    00336
    00337     tuple->Federation = federation_reference ;
    00338     tuple->Federate = federate_reference ;
    00339     tuple->BestEffortLink->attach(ServerSocketUDP->returnSocket(), address,
    00340                                   port);
    00341 }
    00342
    00343 }
    00344
    00345 // $Id: SocketServer.cc,v 3.18 2008/10/13 10:06:48 erk Exp $