transport.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. Copyright (c) 2012-2014 Martin Sustrik All rights reserved.
  3. Copyright (c) 2013 GoPivotal, Inc. All rights reserved.
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"),
  6. to deal in the Software without restriction, including without limitation
  7. the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. and/or sell copies of the Software, and to permit persons to whom
  9. the Software is furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included
  11. in all copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15. THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  17. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  18. IN THE SOFTWARE.
  19. */
  20. #ifndef NN_TRANSPORT_INCLUDED
  21. #define NN_TRANSPORT_INCLUDED
  22. #include "nn.h"
  23. #include "aio/fsm.h"
  24. #include "utils/list.h"
  25. #include "utils/msg.h"
  26. #include <stddef.h>
  27. /* This is the API between the nanomsg core and individual transports. */
  28. struct nn_sock;
  29. struct nn_cp;
  30. /******************************************************************************/
  31. /* Container for transport-specific socket options. */
  32. /******************************************************************************/
  33. struct nn_optset;
  34. struct nn_optset_vfptr {
  35. void (*destroy) (struct nn_optset *self);
  36. int (*setopt) (struct nn_optset *self, int option, const void *optval,
  37. size_t optvallen);
  38. int (*getopt) (struct nn_optset *self, int option, void *optval,
  39. size_t *optvallen);
  40. };
  41. struct nn_optset {
  42. const struct nn_optset_vfptr *vfptr;
  43. };
  44. /******************************************************************************/
  45. /* The base class for endpoints. */
  46. /******************************************************************************/
  47. /* The best way to think about endpoints is that endpoint is an object created
  48. by each nn_bind() or nn_connect() call. Each endpoint is associated with
  49. exactly one address string (e.g. "tcp://127.0.0.1:5555"). */
  50. struct nn_epbase;
  51. struct nn_epbase_vfptr {
  52. /* Ask the endpoint to stop itself. The endpoint is allowed to linger
  53. to send the pending outbound data. When done, it reports the fact by
  54. invoking nn_epbase_stopped() function. */
  55. void (*stop) (struct nn_epbase *self);
  56. /* Deallocate the endpoint object. */
  57. void (*destroy) (struct nn_epbase *self);
  58. };
  59. struct nn_epbase {
  60. const struct nn_epbase_vfptr *vfptr;
  61. struct nn_ep *ep;
  62. };
  63. /* Creates a new endpoint. 'hint' parameter is an opaque value that
  64. was passed to transport's bind or connect function. */
  65. void nn_epbase_init (struct nn_epbase *self,
  66. const struct nn_epbase_vfptr *vfptr, void *hint);
  67. /* Notify the user that stopping is done. */
  68. void nn_epbase_stopped (struct nn_epbase *self);
  69. /* Terminate the epbase object. */
  70. void nn_epbase_term (struct nn_epbase *self);
  71. /* Returns the AIO context associated with the endpoint. */
  72. struct nn_ctx *nn_epbase_getctx (struct nn_epbase *self);
  73. /* Returns the address string associated with this endpoint. */
  74. const char *nn_epbase_getaddr (struct nn_epbase *self);
  75. /* Retrieve value of a socket option. */
  76. void nn_epbase_getopt (struct nn_epbase *self, int level, int option,
  77. void *optval, size_t *optvallen);
  78. /* Returns 1 is the specified socket type is a valid peer for this socket,
  79. or 0 otherwise. */
  80. int nn_epbase_ispeer (struct nn_epbase *self, int socktype);
  81. /* Notifies a monitoring system the error on this endpoint */
  82. void nn_epbase_set_error(struct nn_epbase *self, int errnum);
  83. /* Notifies a monitoring system that error is gone */
  84. void nn_epbase_clear_error(struct nn_epbase *self);
  85. /* Increments statistics counters in the socket structure */
  86. void nn_epbase_stat_increment(struct nn_epbase *self, int name, int increment);
  87. /******************************************************************************/
  88. /* The base class for pipes. */
  89. /******************************************************************************/
  90. /* Pipe represents one "connection", i.e. perfectly ordered uni- or
  91. bi-directional stream of messages. One endpoint can create multiple pipes
  92. (for example, bound TCP socket is an endpoint, individual accepted TCP
  93. connections are represented by pipes. */
  94. struct nn_pipebase;
  95. /* This value is returned by pipe's send and recv functions to signalise that
  96. more sends/recvs are not possible at the moment. From that moment on,
  97. the core will stop invoking the function. To re-establish the message
  98. flow nn_pipebase_received (respectively nn_pipebase_sent) should
  99. be called. */
  100. #define NN_PIPEBASE_RELEASE 1
  101. /* Specifies that received message is already split into header and body.
  102. This flag is used only by inproc transport to avoid merging and re-splitting
  103. the messages passed with a single process. */
  104. #define NN_PIPEBASE_PARSED 2
  105. struct nn_pipebase_vfptr {
  106. /* Send a message to the network. The function can return either error
  107. (negative number) or any combination of the flags defined above. */
  108. int (*send) (struct nn_pipebase *self, struct nn_msg *msg);
  109. /* Receive a message from the network. The function can return either error
  110. (negative number) or any combination of the flags defined above. */
  111. int (*recv) (struct nn_pipebase *self, struct nn_msg *msg);
  112. };
  113. /* Endpoint specific options. Same restrictions as for nn_pipebase apply */
  114. struct nn_ep_options
  115. {
  116. int sndprio;
  117. int rcvprio;
  118. int ipv4only;
  119. };
  120. /* The member of this structure are used internally by the core. Never use
  121. or modify them directly from the transport. */
  122. struct nn_pipebase {
  123. struct nn_fsm fsm;
  124. const struct nn_pipebase_vfptr *vfptr;
  125. uint8_t state;
  126. uint8_t instate;
  127. uint8_t outstate;
  128. struct nn_sock *sock;
  129. void *data;
  130. struct nn_fsm_event in;
  131. struct nn_fsm_event out;
  132. struct nn_ep_options options;
  133. };
  134. /* Initialise the pipe. */
  135. void nn_pipebase_init (struct nn_pipebase *self,
  136. const struct nn_pipebase_vfptr *vfptr, struct nn_epbase *epbase);
  137. /* Terminate the pipe. */
  138. void nn_pipebase_term (struct nn_pipebase *self);
  139. /* Call this function once the connection is established. */
  140. int nn_pipebase_start (struct nn_pipebase *self);
  141. /* Call this function once the connection is broken. */
  142. void nn_pipebase_stop (struct nn_pipebase *self);
  143. /* Call this function when new message was fully received. */
  144. void nn_pipebase_received (struct nn_pipebase *self);
  145. /* Call this function when current outgoing message was fully sent. */
  146. void nn_pipebase_sent (struct nn_pipebase *self);
  147. /* Retrieve value of a socket option. */
  148. void nn_pipebase_getopt (struct nn_pipebase *self, int level, int option,
  149. void *optval, size_t *optvallen);
  150. /* Returns 1 is the specified socket type is a valid peer for this socket,
  151. or 0 otherwise. */
  152. int nn_pipebase_ispeer (struct nn_pipebase *self, int socktype);
  153. /******************************************************************************/
  154. /* The transport class. */
  155. /******************************************************************************/
  156. struct nn_transport {
  157. /* Name of the transport as it appears in the connection strings ("tcp",
  158. "ipc", "inproc" etc. */
  159. const char *name;
  160. /* ID of the transport. */
  161. int id;
  162. /* Following methods are guarded by a global critical section. Two of these
  163. function will never be invoked in parallel. The first is called when
  164. the library is initialised, the second one when it is terminated, i.e.
  165. when there are no more open sockets. Either of them can be set to NULL
  166. if no specific initialisation/termination is needed. */
  167. void (*init) (void);
  168. void (*term) (void);
  169. /* Each of these functions creates an endpoint and returns the newly
  170. created endpoint in 'epbase' parameter. 'hint' is in opaque pointer
  171. to be passed to nn_epbase_init(). The epbase object can then be used
  172. to retrieve the address to bind/connect to. These functions are guarded
  173. by a socket-wide critical section. Two of these function will never be
  174. invoked in parallel on the same socket. */
  175. int (*bind) (void *hint, struct nn_epbase **epbase);
  176. int (*connect) (void *hint, struct nn_epbase **epbase);
  177. /* Create an object to hold transport-specific socket options.
  178. Set this member to NULL in case there are no transport-specific
  179. socket options available. */
  180. struct nn_optset *(*optset) (void);
  181. /* This member is used exclusively by the core. Never touch it directly
  182. from the transport. */
  183. struct nn_list_item item;
  184. };
  185. #endif