PacketPassInterface.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. /**
  2. * @file PacketPassInterface.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. *
  22. * @section DESCRIPTION
  23. *
  24. * Interface allowing a packet sender to pass data packets to a packet receiver.
  25. */
  26. #ifndef BADVPN_FLOW_PACKETPASSINTERFACE_H
  27. #define BADVPN_FLOW_PACKETPASSINTERFACE_H
  28. #include <stdint.h>
  29. #include <stddef.h>
  30. #include <misc/dead.h>
  31. #include <misc/debug.h>
  32. #include <system/DebugObject.h>
  33. /**
  34. * Handler called at the receiver when {@link PacketPassInterface_Sender_Send} is called
  35. * from the sender.
  36. * It is guaranteed that the interface is in not sending state.
  37. * It is guaranteed that the handler is not being called from within Send or Cancel handlers.
  38. *
  39. * @param user value supplied to {@link PacketPassInterface_Init}
  40. * @param data pointer to packet being sent. May be NULL if data_len=0.
  41. * @param data_len length of the packet being sent. Will be >=0 and <=MTU.
  42. * @return - 1 if the receiver accepts the packet immediately. The interface remains in
  43. * not sending state. The receiver may not use the provided data after the handler
  44. * returns.
  45. * - 0 if the receiver cannot accept the packet immediately. The interface enters
  46. * sending state as the handler returns. The receiver may use the provided data
  47. * as long as it needs to. When it's done processing the packet and doesn't need
  48. * the data any more, it must call {@link PacketPassInterface_Done}.
  49. */
  50. typedef int (*PacketPassInterface_handler_send) (void *user, uint8_t *data, int data_len);
  51. /**
  52. * Handler called at the receiver when {@link PacketPassInterface_Sender_Cancel} is called
  53. * from the sender.
  54. * The buffer is still available inside the handler. It is no longer available
  55. * after the handler returns.
  56. * It is guaranteed that the interface is in sending state.
  57. * The interface enters not sending state as the handler returns.
  58. * It is guaranteed that the handler is not being called from within Send or Cancel handlers.
  59. *
  60. * @param user value supplied to {@link PacketPassInterface_Init}
  61. */
  62. typedef void (*PacketPassInterface_handler_cancel) (void *user);
  63. /**
  64. * Handler called at the sender when {@link PacketPassInterface_Done} is called from the receiver.
  65. * The receiver will no longer use the packet it was provided with.
  66. * It is guaranteed that the interface was in sending state.
  67. * The interface enters not sending state before the handler is called.
  68. * It is guaranteed that the handler is not being called from within Send, Cancel or Done handlers.
  69. *
  70. * @param user value supplied to {@link PacketPassInterface_Sender_Init}
  71. */
  72. typedef void (*PacketPassInterface_handler_done) (void *user);
  73. /**
  74. * Interface allowing a packet sender to pass data packets to a packet receiver.
  75. * The sender passes a packet by providing the receiver with a pointer
  76. * to a packet. The receiver may then either accept the packet immediately,
  77. * or tell the sender to wait for the packet to be processed and inform it
  78. * when it's done.
  79. */
  80. typedef struct {
  81. DebugObject d_obj;
  82. // receiver data
  83. int mtu;
  84. PacketPassInterface_handler_send handler_send;
  85. PacketPassInterface_handler_cancel handler_cancel;
  86. void *user_receiver;
  87. // sender data
  88. PacketPassInterface_handler_done handler_done;
  89. void *user_sender;
  90. // debug vars
  91. #ifndef NDEBUG
  92. dead_t debug_dead;
  93. int debug_busy;
  94. int debug_in_send;
  95. int debug_in_done;
  96. #endif
  97. } PacketPassInterface;
  98. /**
  99. * Initializes the interface. The sender portion must also be initialized
  100. * with {@link PacketPassInterface_Sender_Init} before I/O can start.
  101. * The interface is initialized in not sending state.
  102. *
  103. * @param i the object
  104. * @param mtu maximum packet size the receiver can accept. Must be >=0.
  105. * @param handler_send handler called when the sender wants to send a packet
  106. * @param user arbitrary value that will be passed to receiver callback functions
  107. */
  108. static void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_send, void *user);
  109. /**
  110. * Frees the interface.
  111. *
  112. * @param i the object
  113. */
  114. static void PacketPassInterface_Free (PacketPassInterface *i);
  115. /**
  116. * Enables cancel functionality for the interface.
  117. * May only be called once for the interface.
  118. *
  119. * @param i the object
  120. * @param handler_cancel callback function invoked when the sender wants to cancel sending
  121. */
  122. static void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_cancel handler_cancel);
  123. /**
  124. * Notifies the sender that the receiver has finished processing the packet being sent.
  125. * The receiver must not use the data it was provided any more.
  126. * The interface must be in sending state.
  127. * The interface enters not sending state before notifying the sender.
  128. * Must not be called from within Send, Cancel or Done handlers.
  129. *
  130. * Be aware that the sender may attempt to send packets from within this function.
  131. *
  132. * @param i the object
  133. */
  134. static void PacketPassInterface_Done (PacketPassInterface *i);
  135. /**
  136. * Returns the maximum packet size the receiver can accept.
  137. *
  138. * @return maximum packet size. Will be >=0.
  139. */
  140. static int PacketPassInterface_GetMTU (PacketPassInterface *i);
  141. /**
  142. * Initializes the sender portion of the interface.
  143. *
  144. * @param i the object
  145. * @param handler_done handler called when the receiver has finished processing a packet
  146. * @param user arbitrary value that will be passed to sender callback functions
  147. */
  148. static void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user);
  149. /**
  150. * Attempts to send a packet.
  151. * The interface must be in not sending state.
  152. * Must not be called from within Send or Cancel handlers.
  153. *
  154. * @param i the object
  155. * @param data pointer to the packet to send. If the size of the packet is zero, this argument
  156. * is ignored.
  157. * @param data_len length of the packet. Must be >=0 and <=MTU.
  158. * @return - 1 if the packet was accepted by the receiver. The packet is no longer needed.
  159. * The interface remains in not sending state.
  160. * - 0 if the packet could not be accepted immediately and is being processed.
  161. * The interface enters sending state, and the packet must stay accessible while the
  162. * receiver is processing it. When the receiver is done processing it, the
  163. * {@link PacketPassInterface_handler_done} handler will be called.
  164. */
  165. static int PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len);
  166. /**
  167. * Cancels sending a packet.
  168. * Cancel functionality must be available for the interface.
  169. * The buffer must still be available while calling this.
  170. * The buffer is no longer needed after this function returns.
  171. * The interface must be in sending state.
  172. * The interface enters not sending state.
  173. * Must not be called from within Send or Cancel handlers.
  174. *
  175. * @param i the object
  176. */
  177. static void PacketPassInterface_Sender_Cancel (PacketPassInterface *i);
  178. /**
  179. * Determines if the interface supports cancel functionality.
  180. *
  181. * @param i the object
  182. * @return 1 if the interface supports cancel functionality, 0 if not
  183. */
  184. static int PacketPassInterface_HasCancel (PacketPassInterface *i);
  185. #ifndef NDEBUG
  186. /**
  187. * Determines if we are in a Send or Cancel call.
  188. * Only available if NDEBUG is not defined.
  189. *
  190. * @param i the object
  191. * @return 1 if in a Send or Cancel call, 0 if not
  192. */
  193. static int PacketPassInterface_InClient (PacketPassInterface *i);
  194. /**
  195. * Determines if we are in a Done call.
  196. * Only available if NDEBUG is not defined.
  197. *
  198. * @param i the object
  199. * @return 1 if in a Done call, 0 if not
  200. */
  201. static int PacketPassInterface_InDone (PacketPassInterface *i);
  202. #endif
  203. void PacketPassInterface_Init (PacketPassInterface *i, int mtu, PacketPassInterface_handler_send handler_send, void *user)
  204. {
  205. ASSERT(mtu >= 0)
  206. i->mtu = mtu;
  207. i->handler_send = handler_send;
  208. i->handler_cancel = NULL;
  209. i->user_receiver = user;
  210. i->handler_done = NULL;
  211. i->user_sender = NULL;
  212. // init debugging
  213. #ifndef NDEBUG
  214. DEAD_INIT(i->debug_dead);
  215. i->debug_busy = 0;
  216. i->debug_in_send = 0;
  217. i->debug_in_done = 0;
  218. #endif
  219. // init debug object
  220. DebugObject_Init(&i->d_obj);
  221. }
  222. void PacketPassInterface_Free (PacketPassInterface *i)
  223. {
  224. // free debug object
  225. DebugObject_Free(&i->d_obj);
  226. // free debugging
  227. #ifndef NDEBUG
  228. DEAD_KILL(i->debug_dead);
  229. #endif
  230. }
  231. void PacketPassInterface_EnableCancel (PacketPassInterface *i, PacketPassInterface_handler_cancel handler_cancel)
  232. {
  233. ASSERT(!i->handler_cancel)
  234. ASSERT(handler_cancel)
  235. i->handler_cancel = handler_cancel;
  236. }
  237. void PacketPassInterface_Done (PacketPassInterface *i)
  238. {
  239. ASSERT(i->debug_busy)
  240. ASSERT(!i->debug_in_send)
  241. ASSERT(!i->debug_in_done)
  242. #ifndef NDEBUG
  243. i->debug_busy = 0;
  244. i->debug_in_done = 1;
  245. DEAD_ENTER(i->debug_dead)
  246. #endif
  247. i->handler_done(i->user_sender);
  248. #ifndef NDEBUG
  249. if (DEAD_LEAVE(i->debug_dead)) {
  250. return;
  251. }
  252. i->debug_in_done = 0;
  253. #endif
  254. }
  255. int PacketPassInterface_GetMTU (PacketPassInterface *i)
  256. {
  257. return i->mtu;
  258. }
  259. void PacketPassInterface_Sender_Init (PacketPassInterface *i, PacketPassInterface_handler_done handler_done, void *user)
  260. {
  261. i->handler_done = handler_done;
  262. i->user_sender = user;
  263. }
  264. int PacketPassInterface_Sender_Send (PacketPassInterface *i, uint8_t *data, int data_len)
  265. {
  266. ASSERT(!i->debug_busy)
  267. ASSERT(!i->debug_in_send)
  268. ASSERT(data_len >= 0)
  269. ASSERT(data_len <= i->mtu)
  270. ASSERT(!(data_len > 0) || data)
  271. #ifndef NDEBUG
  272. i->debug_in_send = 1;
  273. DEAD_ENTER(i->debug_dead)
  274. #endif
  275. int res = i->handler_send(i->user_receiver, data, data_len);
  276. #ifndef NDEBUG
  277. if (DEAD_LEAVE(i->debug_dead)) {
  278. return -1;
  279. }
  280. i->debug_in_send = 0;
  281. ASSERT(res == 0 || res == 1)
  282. if (!res) {
  283. i->debug_busy = 1;
  284. }
  285. #endif
  286. return res;
  287. }
  288. void PacketPassInterface_Sender_Cancel (PacketPassInterface *i)
  289. {
  290. ASSERT(i->handler_cancel)
  291. ASSERT(i->debug_busy)
  292. ASSERT(!i->debug_in_send)
  293. #ifndef NDEBUG
  294. i->debug_in_send = 1;
  295. DEAD_ENTER(i->debug_dead)
  296. #endif
  297. i->handler_cancel(i->user_receiver);
  298. #ifndef NDEBUG
  299. if (DEAD_LEAVE(i->debug_dead)) {
  300. return;
  301. }
  302. ASSERT(i->debug_in_send)
  303. i->debug_in_send = 0;
  304. i->debug_busy = 0;
  305. #endif
  306. }
  307. int PacketPassInterface_HasCancel (PacketPassInterface *i)
  308. {
  309. return !!i->handler_cancel;
  310. }
  311. #ifndef NDEBUG
  312. int PacketPassInterface_InClient (PacketPassInterface *i)
  313. {
  314. return i->debug_in_send;
  315. }
  316. int PacketPassInterface_InDone (PacketPassInterface *i)
  317. {
  318. return i->debug_in_done;
  319. }
  320. #endif
  321. #endif