net.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /** @file net.c
  2. * @brief Class for comfortable send and receive data to and from socket.
  3. * Class supports timeout for all receive, send functions. It supports signal
  4. * mask to specify signals that can interrupt send/receive operation. It
  5. * supports isbreak_func() callback function for consistent working with
  6. * signals and remove race conditions. It's hard to specify all necessary
  7. * parameter as a function argument so class hides long functions from user.
  8. * Parameters of sending or receving can be specified using class methods.
  9. */
  10. #include <stdlib.h>
  11. #include <stdint.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <assert.h>
  15. #include <unistd.h>
  16. #include <errno.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <fcntl.h>
  20. #include <sys/socket.h>
  21. #include <sys/un.h>
  22. #include <arpa/inet.h>
  23. #include <time.h>
  24. #include <signal.h>
  25. #include "faux/faux.h"
  26. #include "faux/str.h"
  27. #include "faux/net.h"
  28. #include "private.h"
  29. /** @brief Allocates memory for faux_net_t object.
  30. *
  31. * @return Allocated faux_net_t object or NULL on error.
  32. */
  33. faux_net_t *faux_net_new(void)
  34. {
  35. faux_net_t *faux_net = NULL;
  36. faux_net = faux_zmalloc(sizeof(*faux_net));
  37. assert(faux_net);
  38. if (!faux_net)
  39. return NULL;
  40. faux_net->fd = -1;
  41. faux_net->isbreak_func = NULL;
  42. faux_net_sigmask_fill(faux_net);
  43. faux_net_set_timeout(faux_net, NULL);
  44. return faux_net;
  45. }
  46. /** @brief Frees previously allocated faux_net_t object.
  47. *
  48. * @param [in] faux_net Allocated faux_net_t object.
  49. */
  50. void faux_net_free(faux_net_t *faux_net)
  51. {
  52. if (!faux_net)
  53. return;
  54. faux_free(faux_net);
  55. }
  56. /** @brief Sets system descriptor to work with.
  57. *
  58. * It's a socket descriptor. Object will operate over this descriptor.
  59. *
  60. * @param [in] faux_net The faux_net_t object.
  61. * @param [in] fd The descriptor to link object to it.
  62. */
  63. void faux_net_set_fd(faux_net_t *faux_net, int fd)
  64. {
  65. if (!faux_net)
  66. return;
  67. faux_net->fd = fd;
  68. }
  69. /** @brief Unsets socket descriptor.
  70. *
  71. * @param [in] faux_net The faux_net_t object.
  72. */
  73. void faux_net_unset_fd(faux_net_t *faux_net)
  74. {
  75. if (!faux_net)
  76. return;
  77. faux_net->fd = -1;
  78. }
  79. /** @brief Gets file descriptor from object.
  80. *
  81. * @param [in] faux_net The faux_net_t object.
  82. * @return File descriptor from object.
  83. */
  84. int faux_net_get_fd(faux_net_t *faux_net)
  85. {
  86. if (!faux_net)
  87. return -1;
  88. return faux_net->fd;
  89. }
  90. /** @brief Sets timeout for send operation.
  91. *
  92. * @param [in] faux_net The faux_net_t object.
  93. * @param [in] send_timeout Timeout to set.
  94. */
  95. void faux_net_set_send_timeout(faux_net_t *faux_net, struct timespec *send_timeout)
  96. {
  97. assert(faux_net);
  98. if (!faux_net)
  99. return;
  100. if (!send_timeout) {
  101. faux_net->send_timeout = NULL;
  102. } else {
  103. faux_net->send_timeout_val = *send_timeout;
  104. faux_net->send_timeout = &(faux_net->send_timeout_val);
  105. }
  106. }
  107. /** @brief Sets timeout for receive operation.
  108. *
  109. * @param [in] faux_net The faux_net_t object.
  110. * @param [in] send_timeout Timeout to set.
  111. */
  112. void faux_net_set_recv_timeout(faux_net_t *faux_net, struct timespec *recv_timeout)
  113. {
  114. assert(faux_net);
  115. if (!faux_net)
  116. return;
  117. if (!recv_timeout) {
  118. faux_net->recv_timeout = NULL;
  119. } else {
  120. faux_net->recv_timeout_val = *recv_timeout;
  121. faux_net->recv_timeout = &(faux_net->recv_timeout_val);
  122. }
  123. }
  124. /** @brief Sets timeout both for send and receive operation.
  125. *
  126. * @param [in] faux_net The faux_net_t object.
  127. * @param [in] send_timeout Timeout to set.
  128. */
  129. void faux_net_set_timeout(faux_net_t *faux_net, struct timespec *timeout)
  130. {
  131. assert(faux_net);
  132. if (!faux_net)
  133. return;
  134. faux_net_set_send_timeout(faux_net, timeout);
  135. faux_net_set_recv_timeout(faux_net, timeout);
  136. }
  137. /** @brief Sets isbreak_func() funtion for network operation.
  138. *
  139. * Callback function informs network functions to interrupt actions.
  140. * See faux_send_block() function for explanation.
  141. *
  142. * @sa faux_send_block()
  143. * @param [in] faux_net The faux_net_t object.
  144. * @param [in] isbreak_func Callback function.
  145. */
  146. void faux_net_set_isbreak_func(faux_net_t *faux_net, int (*isbreak_func)(void))
  147. {
  148. assert(faux_net);
  149. if (!faux_net)
  150. return;
  151. faux_net->isbreak_func = isbreak_func;
  152. }
  153. /** @brief Emptyes signal mask using while network operations.
  154. *
  155. * @param [in] faux_net The faux_net_t object.
  156. */
  157. void faux_net_sigmask_empty(faux_net_t *faux_net)
  158. {
  159. assert(faux_net);
  160. if (!faux_net)
  161. return;
  162. sigemptyset(&(faux_net->sigmask));
  163. }
  164. /** @brief Fills signal mask using while network operations.
  165. *
  166. * @param [in] faux_net The faux_net_t object.
  167. */
  168. void faux_net_sigmask_fill(faux_net_t *faux_net)
  169. {
  170. assert(faux_net);
  171. if (!faux_net)
  172. return;
  173. sigfillset(&(faux_net->sigmask));
  174. }
  175. /** @brief Adds signal to signal mask using while network operations.
  176. *
  177. * @param [in] faux_net The faux_net_t object.
  178. * @param [in] signum Signal number to add.
  179. */
  180. void faux_net_sigmask_add(faux_net_t *faux_net, int signum)
  181. {
  182. assert(faux_net);
  183. if (!faux_net)
  184. return;
  185. sigaddset(&(faux_net->sigmask), signum);
  186. }
  187. /** @brief Removes signal to signal mask using while network operations.
  188. *
  189. * @param [in] faux_net The faux_net_t object.
  190. * @param [in] signum Signal number to remove.
  191. */
  192. void faux_net_sigmask_del(faux_net_t *faux_net, int signum)
  193. {
  194. assert(faux_net);
  195. if (!faux_net)
  196. return;
  197. sigdelset(&(faux_net->sigmask), signum);
  198. }
  199. /** @brief Sends data to socket associated with given objects.
  200. *
  201. * Function uses previously set parameters such as descriptor, timeout,
  202. * signal mask, callback function.
  203. *
  204. * @param [in] faux_net The faux_net_t object.
  205. * @param [in] buf Data buffer to send
  206. * @param [in] n Number of bytes to send.
  207. * @return Number of bytes was succesfully sent or < 0 on error.
  208. */
  209. ssize_t faux_net_send(faux_net_t *faux_net, const void *buf, size_t n)
  210. {
  211. return faux_send_block(faux_net->fd, buf, n, faux_net->send_timeout,
  212. &(faux_net->sigmask), faux_net->isbreak_func);
  213. }
  214. /** @brief Sends data vector to socket associated with given objects.
  215. *
  216. * Function uses previously set parameters such as descriptor, timeout,
  217. * signal mask, callback function.
  218. *
  219. * @param [in] faux_net The faux_net_t object.
  220. * @param [in] iov Array of struct iovec structures.
  221. * @param [in] iovcnt Number of iov array members.
  222. * @return Number of bytes was succesfully sent or < 0 on error.
  223. */
  224. ssize_t faux_net_sendv(faux_net_t *faux_net,
  225. const struct iovec *iov, int iovcnt)
  226. {
  227. return faux_sendv_block(faux_net->fd, iov, iovcnt, faux_net->send_timeout,
  228. &(faux_net->sigmask), faux_net->isbreak_func);
  229. }
  230. /** @brief Receives data from socket associated with given objects.
  231. *
  232. * Function uses previously set parameters such as descriptor, timeout,
  233. * signal mask, callback function.
  234. *
  235. * @param [in] faux_net The faux_net_t object.
  236. * @param [in] buf Data buffer for receiving.
  237. * @param [in] n Number of bytes to receive.
  238. * @return Number of bytes was succesfully received or < 0 on error.
  239. */
  240. ssize_t faux_net_recv(faux_net_t *faux_net, void *buf, size_t n)
  241. {
  242. return faux_recv_block(faux_net->fd, buf, n, faux_net->recv_timeout,
  243. &(faux_net->sigmask), faux_net->isbreak_func);
  244. }
  245. /** @brief Receives data vector from socket associated with given objects.
  246. *
  247. * Function uses previously set parameters such as descriptor, timeout,
  248. * signal mask, callback function.
  249. *
  250. * @param [in] faux_net The faux_net_t object.
  251. * @param [in] iov Array of struct iovec structures.
  252. * @param [in] iovcnt Number of iov array members.
  253. * @return Number of bytes was succesfully received or < 0 on error.
  254. */
  255. ssize_t faux_net_recvv(faux_net_t *faux_net, struct iovec *iov, int iovcnt)
  256. {
  257. return faux_recvv_block(faux_net->fd, iov, iovcnt, faux_net->recv_timeout,
  258. &(faux_net->sigmask), faux_net->isbreak_func);
  259. }