Updated license
[anna.git] / include / anna / comm / Socket.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_Socket_hpp
38 #define anna_comm_Socket_hpp
39
40 #include <unistd.h>
41 #include <sys/socket.h>
42 #include <sys/un.h>
43
44 #include <anna/config/defines.hpp>
45 #include <anna/core/mt/Mutex.hpp>
46
47 #include <anna/comm/INetAddress.hpp>
48 #include <anna/comm/AccessPoint.hpp>
49
50 namespace anna {
51
52 class DataBlock;
53
54 namespace xml {
55 class Node;
56 }
57
58 namespace comm {
59
60 class TransportFactory;
61 class ReceiverFactory;
62
63 /**
64    Esta clase es la superclase de la que heredan todos los socket definidos en este paquete. Es usada tanto para
65    crear socket de la parte cliente y de la parte servidora.
66 */
67 class Socket : public Mutex  {
68 public:
69   /**
70      Tipos de dominios soportados.
71   */
72   struct Domain { enum _v {  Unix = PF_UNIX, Inet = PF_INET } ;  };
73
74   /**
75      Tipos de sockets soportados.
76   */
77   struct Type { enum _v {  Stream = SOCK_STREAM, Datagram = SOCK_DGRAM, Raw = SOCK_RAW } ;  };
78
79   /**
80      Tipos de notificaciones que nos puede indicar el Socket.
81      \see Socket
82   */
83   struct Notify {
84     enum _v {
85       None,          /**< No hay actividad en el socket */
86       ReceiveData,   /**< Datos recibidos */
87       Close,         /**< El extremo remoto ha cerrado el socket */
88       Corrupt        /**< El mensaje recibido no ha sido reconocido por la capa de transporte */
89     };
90   };
91
92   /**
93      Destructor.
94   */
95   virtual ~Socket();
96
97   /**
98      Devuelve el descriptor de fichero asociado a este socket.
99      @return El descriptor de fichero asociado a este socke. Si el socket no ha sido creado devolver�-1.
100   */
101   int getfd() const throw() { return a_fd; }
102
103   /**
104      Devuelve el tipo de socket.
105      \return El tipo de socket.
106   */
107   Type::_v getType() const throw() { return a_type; }
108
109   /**
110      Devuelve el dominio de este socket.
111      \return El dominio de este socket.
112   */
113   Domain::_v getDomain() const throw() { return a_domain; }
114
115   /**
116      Devuelve la categoria asociada a este socket.
117      \return La categoria asociada a este socket.
118   */
119   int getCategory() const throw() { return a_category; }
120
121   /**
122      Informa sobre si el socket es capaz de procesar un determinado protocolo de transporte.
123      \param transportClassName Normalmente se pasara el resultado del metodo \em className de
124      alguno de los protocolos definidos, por ejemplo, Transport::className o
125      LiteTransport::className
126      \return \em true si soporta el nombre de protocolo recibido como parametro o \em false
127      en otro caso.
128   */
129   bool support(const char* transportClassName) const throw();
130
131   /**
132      Devuelve el estado de la conexion de este socket.
133
134      @return \em true si el servidor de socket ha sido conectado o \em false en otro caso.
135   */
136   bool isBound() const throw() { return a_isBound; }
137
138   /**
139      Devuelve el estado del socket.
140      @return \em true si el socket este abierto o \em false en otro caso.
141   */
142   bool isOpened() const throw() { return a_fd != -1; }
143
144   /**
145    * Devuelve \em false si el socket usa un protocolo de comunicaciones seguro o \em false
146    * en otro caso.
147    * \return \em false si el socket usa un protocolo de comunicaciones seguro o \em false
148    * en otro caso.
149    */
150   virtual bool isSecure() const throw() { return false; }
151
152   /**
153      Devuelve la direccion local del socket.
154      \return La direccion local del socket.
155   */
156   const AccessPoint& getLocalAccessPoint() const throw() { return a_localAccessPoint; }
157
158   /**
159      Devuelve la factoria de la capa de transporte usada en este socket.
160      \return la factoria de la capa de transporte usada en este socket.
161   */
162   TransportFactory* getTransportFactory() const throw() { return a_transportFactory; }
163
164   /**
165      Devuelve la factoria de receptores usada en este socket.
166      \return la factoria de receptores usada en este socket.
167   */
168   ReceiverFactory* getReceiverFactory() throw() { return a_receiverFactory; }
169
170   /**
171      Activa o desactiva el modo de bloqueo.
172      \param blockingMode \em true si queremos activar el bloqueo o \em false en otro caso.
173      @return El modo de bloqueo establecido antes de invocar este masodo.
174   */
175   bool setBlockingMode(const bool blockingMode) throw(RuntimeException);
176
177   /**
178      Activa o desactiva el modo de reuso de la direccion.
179      \param reuseMode \em true si queremos activar el reuso o \em false en otro caso.
180      \warning Solo servira para acelerar el uso del socket una vez que el proceso que lo tenia
181      halla dejado de funcionar.
182      \return El modo de reuso establecido antes de invocar a este metodo.
183   */
184   bool setReuseMode(const bool reuseMode) throw(RuntimeException);
185
186   /**
187      Establece la capa de transporte usada en este socket.
188      \warning Exclusivamente uso interno.
189   */
190   void setTransportFactory(TransportFactory* transportFactory)  throw() { a_transportFactory = transportFactory; }
191
192   /**
193      Establece la factoria de receptores usada por este socket.
194      \param receiverFactory Factoria de receptores desde la que obtener el receptor asociado a este Socket.
195   */
196   void setReceiverFactory(ReceiverFactory& receiverFactory)  throw() { a_receiverFactory = &receiverFactory; }
197
198   /**
199      Establece la categoria de este socket.
200      La categoria es una concepto del ambito de la aplicacion que el nucleo de anna.comm
201      no usa para nada. Unicamente hay que tener en cuenta que todos los anna::comm::ClientSocket creados
202      a partir de un anna::comm::ServerSocket comparten su misma categoria.
203      \param category Categoria asociada a este socket.
204   */
205   void setCategory(const int category) throw() { a_category = category; }
206
207   /**
208      Cierra este socket. Si el socket no ha sido creado no tendra ningn efecto.
209   */
210   void close() throw();
211
212   /**
213      Intenta la asociar este socket con los parametros indicados en el constructor.
214   */
215   virtual void bind() throw(RuntimeException);
216
217   /**
218      Devuelve una cadena con la informacion referente a este socket.
219      @return Una cadena con la informacion referente a este socket.
220   */
221   virtual std::string asString() const throw();
222
223   /**
224      Devuelve un nodo XML con la informacion referente a este objeto.
225      \param parent Nodo XML a partir del cual introducir la informacion.
226      \return Un nodo XML con la informacion referente a este objeto.
227   */
228   virtual xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
229
230 protected:
231   const Domain::_v  a_domain;
232   const Type::_v a_type;
233   int a_fd;
234   AccessPoint a_localAccessPoint;
235   bool a_isBound;
236   TransportFactory* a_transportFactory;
237   ReceiverFactory* a_receiverFactory;
238   int a_category;
239
240   /**
241      Crea un servidor de socket liberado.
242      \param domain Dominio del socket.
243      \param type Tipo de socket.
244      \param transportFactory Factoria de protocolos de transporte a usar por este sockets. Si se indica
245      NULL ser usara el protocolo devuelto por anna::comm::Application::getDefaultTransportFactory.
246      \warning La factoria de protocolos debe estar disponible mientras el Socket este activo.
247   */
248   Socket(const Domain::_v domain, const Type::_v type, TransportFactory* transportFactory = NULL);
249
250   /**
251      Crea un socket INET que sera asociado a la direccion y puerto locales indicados.
252
253      \param localAddress Puede ser usado para limitar la direccion por la que atendiende peticiones un servidor de socket
254      instalado en una maquina con mas de una direccion.
255      \param type Tipo de socket.
256      \param transportFactory Factoria de protocolos de transporte a usar por este sockets. Si se indica
257      NULL ser usara el protocolo devuelto por anna::comm::Application::getDefaultTransportFactory.
258      \warning La factoria de protocolos debe estar disponible mientras el Socket este activo.
259   */
260   Socket(const INetAddress& localAddress,  const Type::_v type, TransportFactory* transportFactory = NULL);
261
262   /**
263      Crea un socket UNIX que sera asociado al archivo indicado como parametro.
264
265      \param path Ruta del archivo que vamos a usar para transferir datos a traves de este socket.
266      \param type Tipo de socket.
267      \param transportFactory Factoria de protocolos de transporte a usar por este sockets. Si se indica
268      NULL ser usara el protocolo devuelto por anna::comm::Application::getDefaultTransportFactory.
269   */
270   Socket(const std::string& path, const Type::_v type, TransportFactory* transportFactory = NULL);
271
272   /**
273      Abre el socket.
274   */
275   void open() throw(RuntimeException);
276
277   /**
278      Cierra este socket. Si el socket no ha sido creado no tendra ningn efecto.
279   */
280   virtual void do_close() throw() { ::close(a_fd); }
281
282   /**
283      Asocia este Socket a la direccion recibida como parametro.
284      \warning Exclusivamente uso interno.
285   */
286   virtual int do_bind(const struct sockaddr*, const int) throw(RuntimeException);
287
288   /**
289      Devuelve la cadena correspondiente a la notificacion recibida como parametro.
290      \param v Codigo de notificacion.
291      \return La cadena correspondiente a la notificacion recibida como parametro.
292   */
293   static const char* asText(const Notify::_v v) throw();
294
295 private:
296   bool a_reuseMode;
297 };
298
299 #define anna_socket_assert(a,b) \
300    if ((a)) { \
301       std::string msg (asString ()); \
302       msg += " | "; \
303       msg += b; \
304       throw RuntimeException (msg, __FILE__, __LINE__); \
305    }
306
307 #define anna_comm_socket_check(a,b) \
308    if ((a) < 0) { \
309       const int xerrno = errno; \
310       std::string msg (asString ()); \
311       msg += " | "; \
312       msg += b; \
313       throw RuntimeException (msg, errno, ANNA_FILE_LOCATION); \
314    }
315 }
316 }
317
318
319 #endif
320
321
322