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 $

Generated on Thu Apr 30 15:53:50 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5