Updated license
[anna.git] / include / anna / comm / ServerSocket.hpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_comm_ServerSocket_hpp
38 #define anna_comm_ServerSocket_hpp
39
40 #include <anna/core/util/Recycler.hpp>
41 #include <anna/core/util/Millisecond.hpp>
42
43 #include <anna/comm/Socket.hpp>
44 #include <anna/comm/internal/LocalConnection.hpp>
45
46 namespace anna {
47
48 namespace comm {
49
50 class INetAddress;
51 class BinderSocket;
52
53 /**
54    Esta clase implementa el servidor de Socket. Un servidor de Socket espera las peticiones de entrada procedentes
55    de la red y realiza las operaciones necesarias para tratar la operacion y posiblemente devolver un resultado
56    al peticionario.
57
58    El 'backlog' de un servidor de socket define la longitud maxima que la cola de mensajes pendientes puede alcanzar.
59    Si cliente realiza una peticion mediante una conexion UF_UNIX cuando la cola de mensajes del servidor esta llena
60    recibira un error ECONNREFUSED, aunque normalmente el protocolo subyacente se encarga de retransmitir la peticion
61    un numero indeterminado de veces.
62
63    @see Communicator::accept
64 */
65 class ServerSocket : public Socket {
66 public:
67   /**
68      numero de milisegundos por defecto que espera antes de dar por fallida una asociacion a una
69      direccion.
70   */
71   static const Millisecond DefaultBindDelay;
72
73   typedef Recycler<LocalConnection>::iterator iterator;
74
75   /**
76      Tamao de la cola de mensajes tomado por defecto.
77   */
78   static const int defaultBacklog = 30;
79
80   /**
81      Crea un servidor de socket liberado.
82      \param transportFactory Factoria de protocolos de transporte a usar por este sockets.
83      \param domain Dominio del socket.
84      \param type Tipo de socket.
85      \warning La Factoria de protocolos debe estar disponible mientras el Socket esta activo.
86   */
87   ServerSocket(TransportFactory* transportFactory = NULL, Domain::_v domain = Socket::Domain::Inet, Type::_v type = Socket::Type::Stream) :
88     Socket(domain, type, transportFactory),
89     a_backlog(defaultBacklog),
90     a_sharedBind(false),
91     a_binderSocket(NULL),
92     a_msBindDelay(DefaultBindDelay) {}
93
94   /**
95      Crea un servidor de socket conectado a la direccion y puerto indicado y con la longitud de cola maxima indicada.
96
97      \param localAddress Direccion Local en la que atendera las peticiones.
98      \param transportFactory Factoria de protocolos de transporte a usar por este sockets.
99      \param sharedBind \em true Si puede haber mas de una aplicacion escuchando es esta misma direccion.
100      \warning La factoria de protocolos debe estar disponible mientras el Socket esta activo.
101   */
102   ServerSocket(const INetAddress& localAddress, const bool sharedBind, TransportFactory* transportFactory = NULL) :
103     Socket(localAddress, Socket::Type::Stream, transportFactory),
104     a_backlog(defaultBacklog),
105     a_sharedBind(sharedBind),
106     a_binderSocket(NULL),
107     a_msBindDelay(DefaultBindDelay) {}
108
109   /**
110      Destructor.
111   */
112   virtual ~ServerSocket();
113
114   /**
115      Devuelve el numero de milisegundos esperado al hacer el bind compartido con este sockets
116      antes de considerar que no se puede atender peticiones en esa direccion.
117      \return el numero de milisegundos esperado al hacer el bind compartido con este sockets
118      antes de considerar que no se puede atender peticiones en esa direccion.
119   */
120   const Millisecond &getBindDelay() throw() { return a_msBindDelay; }
121
122   /**
123      Devuelve el socket asociado a este socket de bind compartido.
124      \return El socket asociado a este socket de bind compartido. Puede ser NULL.
125   */
126   BinderSocket* getBinderSocket() throw() { return a_binderSocket; }
127
128   /**
129      Devuelve el modo de asociacion de este socket.
130      \return El modo de asociacion de este socket.
131      \warning El valor devuelto por este metodo solo sera valido despues de ejecutar correctamente
132      el metodo #bind
133   */
134   bool isSharedBind() const throw() { return a_sharedBind; }
135
136   /**
137      Establece el tamao de la cola de mensajes.
138      \param backlog Tamao de la cola de mensajes.
139   */
140   void setBacklog(const int backlog) throw() { a_backlog = backlog; }
141
142   /**
143      Establece el numero de milisegundos esperado al hacer el bind con este sockets antes
144      de considerar que no se puede realizar la conexion.
145
146      \param bindDelay numero de milisegundos esperado al hacer la conexion con este
147      sockets antes de considerar que no se puede realizar la conexion.
148
149      \see #DefaultBindDelay
150
151      \warning Solo tendra efecto en el caso de que el socket tenga activado el modo de 'Bind compartido'.
152   */
153   void setBindDelay(const Millisecond &bindDelay) throw() { a_msBindDelay = bindDelay; }
154
155   /**
156      Metodo que debemos invocar una vez que el ServerSocket esta establecido.
157      \warning Normalmente se invocar�desde Communicator::attach(ServerSocket&,bool)
158   */
159   virtual void prepare() throw(RuntimeException);
160
161   /**
162      Comprueba la conexion establecida y acepta las peticiones. Esta funcin puede bloquear al thread
163      que la invoca mientras no llegue una peticion de apertura de conexion si no hemos establecido el modo
164      no-bloqueante del socket. Ver Socket::setBlockingMode.
165
166      Cada uno de los socket obtenidos con este Metodo debe ser liberado con #release cuando ya no sean
167      necesarios.
168
169      @return Nueva conexion aceptada, pendiente de pasar los filtros de acceptacion.
170
171      \warning Exclusivamente uso interno.
172   */
173   LocalConnection* accept() throw(RuntimeException);
174
175   /**
176      Libera los recursos del socket recibido como parametro.
177
178      @param localConnection Socket del que vamos a liberar los recursos. Esta instancia deberia haberse obtenido
179      mediante el Metodo #accept, ya que en otro caso los resultados no estan definidos.
180
181      \warning Exclusivamente uso interno.
182   */
183   void release(LocalConnection* localConnection) throw(RuntimeException);
184
185   /**
186      Devuelve un iterador al primer LocalConnection definido.
187      \return un iterador al primer LocalConnection definido.
188   */
189   iterator begin() throw() { return a_localConnections.begin(); }
190
191   /**
192      Devuelve un iterador al ultimo LocalConnection definido.
193      \return un iterador al ultimo LocalConnection definido.
194   */
195   iterator end() throw() { return a_localConnections.end(); }
196
197   /**
198      Devuelve una cadena con la informacion referente a este socket.
199      @return Una cadena con la informacion referente a este socket.
200   */
201   virtual std::string asString() const throw();
202
203   /**
204      Devuelve un nodo XML con la informacion referente a este objeto.
205      \param parent Nodo XML a partir del cual introducir la informacion.
206      \return Un nodo XML con la informacion referente a este objeto.
207   */
208   virtual xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
209
210   /**
211      Metodo manejador de evento que permite ajustar el funcionamiento cuando el nucleo de
212      anna.comm notifica que ha detectado una peticion de conexion desde un proceso
213      remoto a un ServerSocket asociado al comunicador. Permite independencia de dicho
214      comunicador y complementa el control de aceptacion (por defecto, se devuelve true
215      para no influir en la implementacion del metodo analogo en el comunicador).
216
217      @param clientSocket Socket cliente que solicita acceso.
218
219      \return \em true si la conexion es acceptada a \em false en otro caso, en cuyo caso se liberaran
220      automaticamente todos los recursos asociados a la peticion de conexion.
221   */
222   virtual bool eventAcceptConnection(const ClientSocket &clientSocket) throw(RuntimeException) { return true; }
223
224 //   /**
225 //       Informa sobre la rotura de una conexion que se creo a partir de un ServerSocket
226 //
227 //      @param localConnection Socket que se acepto sobre el server socket y que se ha roto.
228 //   */
229 //   virtual void eventBreakLocalConnection (LocalConnection* localConnection) throw (RuntimeException) {;}
230
231
232   /**
233      Devuelve una referencia al contenido apuntado por el iterador.
234      \return una referencia al contenido apuntado por el iterador.
235   */
236   static LocalConnection* localConnection(iterator& ii) throw() { return Recycler<LocalConnection>::data(ii); }
237
238   /**
239      Devuelve el nombre logico de esta clase.
240      \return el nombre logico de esta clase.
241   */
242   static const char* className() throw() { return "anna::comm::ServerSocket"; }
243
244 protected:
245   /**
246      Crea un servidor de socket conectado a la direccion y puerto indicado y con la longitud de cola maxima indicada.
247
248      \param transportFactory Factoria de protocolos de transporte a usar por este sockets.
249      \param localAddress Puede ser usado para limitar la direccion por la que atendiende peticiones un servidor de socket
250      instalado en una maquina con mas de una direccion.
251      \param sharedBind \em true Si puede haber mas de una aplicacion escuchando es esta misma direccion.
252      \param type Tipo de socket.
253      \warning La Factoria de protocolos debe estar disponible mientras el Socket esta activo.
254   */
255   ServerSocket(const INetAddress& localAddress, const bool sharedBind, Type::_v type, TransportFactory* transportFactory = NULL) :
256     Socket(localAddress, type, transportFactory),
257     a_backlog(defaultBacklog),
258     a_sharedBind(false),
259     a_binderSocket(NULL),
260     a_msBindDelay(DefaultBindDelay) {}
261
262 private:
263   int a_backlog;
264   Recycler <LocalConnection> a_localConnections;
265   const bool a_sharedBind;
266   BinderSocket* a_binderSocket;
267   Millisecond a_msBindDelay;
268
269   virtual ClientSocket* allocateClientSocket() const throw();
270   int do_bind(const struct sockaddr *, const int len) throw(RuntimeException);
271
272   friend class BinderSocket;
273 };
274
275 }
276 }
277
278
279 #endif
280
281
282