pass_fd.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26. */
  27. /*
  28. * History:
  29. * --------
  30. * 2002-11-29 created by andrei
  31. * 2003-02-20 added solaris support (! HAVE_MSGHDR_MSG_CONTROL) (andrei)
  32. * 2003-11-03 added send_all, recv_all and updated send/get_fd
  33. * to handle signals (andrei)
  34. * 2005-06-13 added flags to recv_all & receive_fd, to allow full blocking
  35. * or semi-nonblocking mode (andrei)
  36. * 2008-04-30 added MSG_WAITALL emulation for cygwin (andrei)
  37. */
  38. /*!
  39. * \file
  40. * \brief SIP-router core ::
  41. * \ingroup core
  42. * Module: \ref core
  43. */
  44. #ifdef USE_TCP
  45. #include "pass_fd.h"
  46. #include <sys/types.h>
  47. #include <sys/socket.h>
  48. #include <sys/uio.h>
  49. #include <stdlib.h> /* for NULL definition on openbsd */
  50. #include <errno.h>
  51. #include <string.h>
  52. #ifdef NO_MSG_WAITALL
  53. #include <poll.h>
  54. #endif /* NO_MSG_WAITALL */
  55. #include "dprint.h"
  56. /* receive all the data or returns error (handles EINTR etc.)
  57. * params: socket
  58. * data - buffer for the results
  59. * data_len -
  60. * flags - recv flags for the first recv (see recv(2)), only
  61. * 0, MSG_WAITALL and MSG_DONTWAIT make sense
  62. * if flags is set to MSG_DONWAIT (or to 0 and the socket fd is non-blocking),
  63. * and if no data is queued on the fd, recv_all will not wait (it will
  64. * return error and set errno to EAGAIN/EWOULDBLOCK). However if even 1 byte
  65. * is queued, the call will block until the whole data_len was read or an
  66. * error or eof occured ("semi-nonblocking" behaviour, some tcp code
  67. * counts on it).
  68. * if flags is set to MSG_WAITALL it will block even if no byte is available.
  69. *
  70. * returns: bytes read or error (<0)
  71. * can return < data_len if EOF */
  72. int recv_all(int socket, void* data, int data_len, int flags)
  73. {
  74. int b_read;
  75. int n;
  76. #ifdef NO_MSG_WAITALL
  77. struct pollfd pfd;
  78. #endif /* NO_MSG_WAITALL */
  79. b_read=0;
  80. again:
  81. #ifdef NO_MSG_WAITALL
  82. if (flags & MSG_WAITALL){
  83. n=-1;
  84. goto poll_recv; /* simulate MSG_WAITALL */
  85. }
  86. #endif /* NO_MSG_WAITALL */
  87. n=recv(socket, (char*)data, data_len, flags);
  88. if (n<0){
  89. /* error */
  90. if (errno==EINTR) goto again; /* signal, try again */
  91. /* on EAGAIN just return (let the caller know) */
  92. if ((errno==EAGAIN)||(errno==EWOULDBLOCK)) return n;
  93. LM_CRIT("1st recv on %d failed: %s\n",
  94. socket, strerror(errno));
  95. return n;
  96. }
  97. b_read+=n;
  98. while( (b_read!=data_len) && (n)){
  99. #ifdef NO_MSG_WAITALL
  100. /* cygwin & win do not support MSG_WAITALL => workaround using poll */
  101. poll_recv:
  102. n=recv(socket, (char*)data+b_read, data_len-b_read, 0);
  103. #else /* NO_MSG_WAITALL */
  104. n=recv(socket, (char*)data+b_read, data_len-b_read, MSG_WAITALL);
  105. #endif /* NO_MSG_WAITALL */
  106. if (n<0){
  107. /* error */
  108. if (errno==EINTR) continue; /* signal, try again */
  109. #ifdef NO_MSG_WAITALL
  110. if (errno==EAGAIN || errno==EWOULDBLOCK){
  111. /* emulate MSG_WAITALL using poll */
  112. pfd.fd=socket;
  113. pfd.events=POLLIN;
  114. poll_retry:
  115. n=poll(&pfd, 1, -1);
  116. if (n<0){
  117. if (errno==EINTR) goto poll_retry;
  118. LM_CRIT("poll on %d failed: %s\n",
  119. socket, strerror(errno));
  120. return n;
  121. } else continue; /* try recv again */
  122. }
  123. #endif /* NO_MSG_WAITALL */
  124. LM_CRIT("2nd recv on %d failed: %s\n",
  125. socket, strerror(errno));
  126. return n;
  127. }
  128. b_read+=n;
  129. }
  130. return b_read;
  131. }
  132. /* sends all data (takes care of signals) (assumes blocking fd)
  133. * returns number of bytes sent or < 0 for an error */
  134. int send_all(int socket, void* data, int data_len)
  135. {
  136. int n;
  137. again:
  138. n=send(socket, data, data_len, 0);
  139. if (n<0){
  140. /* error */
  141. if (errno==EINTR) goto again; /* signal, try again */
  142. if ((errno!=EAGAIN) &&(errno!=EWOULDBLOCK))
  143. LM_CRIT("send on %d failed: %s\n",
  144. socket, strerror(errno));
  145. }
  146. return n;
  147. }
  148. /* at least 1 byte must be sent! */
  149. int send_fd(int unix_socket, void* data, int data_len, int fd)
  150. {
  151. struct msghdr msg;
  152. struct iovec iov[1];
  153. int ret;
  154. #ifdef HAVE_MSGHDR_MSG_CONTROL
  155. int* pi;
  156. struct cmsghdr* cmsg;
  157. /* make sure msg_control will point to properly aligned data */
  158. union {
  159. struct cmsghdr cm;
  160. char control[CMSG_SPACE(sizeof(fd))];
  161. }control_un;
  162. msg.msg_control=control_un.control;
  163. /* openbsd doesn't like "more space", msg_controllen must not
  164. * include the end padding */
  165. msg.msg_controllen=CMSG_LEN(sizeof(fd));
  166. cmsg=CMSG_FIRSTHDR(&msg);
  167. cmsg->cmsg_level = SOL_SOCKET;
  168. cmsg->cmsg_type = SCM_RIGHTS;
  169. cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
  170. pi=(int*)CMSG_DATA(cmsg);
  171. *pi=fd;
  172. msg.msg_flags=0;
  173. #else
  174. msg.msg_accrights=(caddr_t) &fd;
  175. msg.msg_accrightslen=sizeof(fd);
  176. #endif
  177. msg.msg_name=0;
  178. msg.msg_namelen=0;
  179. iov[0].iov_base=data;
  180. iov[0].iov_len=data_len;
  181. msg.msg_iov=iov;
  182. msg.msg_iovlen=1;
  183. again:
  184. ret=sendmsg(unix_socket, &msg, 0);
  185. if (ret<0){
  186. if (errno==EINTR) goto again;
  187. if ((errno!=EAGAIN) && (errno!=EWOULDBLOCK))
  188. LM_CRIT("sendmsg failed sending %d on %d: %s (%d)\n",
  189. fd, unix_socket, strerror(errno), errno);
  190. }
  191. return ret;
  192. }
  193. /* receives a fd and data_len data
  194. * params: unix_socket
  195. * data
  196. * data_len
  197. * fd - will be set to the passed fd value or -1 if no fd
  198. * was passed
  199. * flags - 0, MSG_DONTWAIT, MSG_WAITALL; same as recv_all flags
  200. * returns: bytes read on success, -1 on error (and sets errno) */
  201. int receive_fd(int unix_socket, void* data, int data_len, int* fd, int flags)
  202. {
  203. struct msghdr msg;
  204. struct iovec iov[1];
  205. int new_fd;
  206. int ret;
  207. int n;
  208. #ifdef NO_MSG_WAITALL
  209. struct pollfd pfd;
  210. int f;
  211. #endif /*NO_MSG_WAITALL */
  212. #ifdef HAVE_MSGHDR_MSG_CONTROL
  213. int* pi;
  214. struct cmsghdr* cmsg;
  215. union{
  216. struct cmsghdr cm;
  217. char control[CMSG_SPACE(sizeof(new_fd))];
  218. }control_un;
  219. msg.msg_control=control_un.control;
  220. msg.msg_controllen=sizeof(control_un.control);
  221. #else
  222. msg.msg_accrights=(caddr_t) &new_fd;
  223. msg.msg_accrightslen=sizeof(int);
  224. #endif
  225. msg.msg_name=0;
  226. msg.msg_namelen=0;
  227. iov[0].iov_base=data;
  228. iov[0].iov_len=data_len;
  229. msg.msg_iov=iov;
  230. msg.msg_iovlen=1;
  231. #ifdef NO_MSG_WAITALL
  232. f=flags & ~MSG_WAITALL;
  233. #endif /* NO_MSG_WAITALL */
  234. again:
  235. #ifdef NO_MSG_WAITALL
  236. ret=recvmsg(unix_socket, &msg, f);
  237. #else /* NO_MSG_WAITALL */
  238. ret=recvmsg(unix_socket, &msg, flags);
  239. #endif /* NO_MSG_WAITALL */
  240. if (ret<0){
  241. if (errno==EINTR) goto again;
  242. if ((errno==EAGAIN)||(errno==EWOULDBLOCK)){
  243. #ifdef NO_MSG_WAITALL
  244. if (flags & MSG_WAITALL){
  245. /* emulate MSG_WAITALL using poll */
  246. pfd.fd=unix_socket;
  247. pfd.events=POLLIN;
  248. poll_again:
  249. ret=poll(&pfd, 1, -1);
  250. if (ret>=0) goto again;
  251. else if (errno==EINTR) goto poll_again;
  252. LM_CRIT("poll on %d failed: %s\n",
  253. unix_socket, strerror(errno));
  254. }
  255. #endif /* NO_MSG_WAITALL */
  256. goto error;
  257. }
  258. LM_CRIT("recvmsg on %d failed: %s\n",
  259. unix_socket, strerror(errno));
  260. goto error;
  261. }
  262. if (ret==0){
  263. /* EOF */
  264. LM_CRIT("EOF on %d\n", unix_socket);
  265. goto error;
  266. }
  267. if (ret<data_len){
  268. LM_WARN("too few bytes read (%d from %d) trying to fix...\n",
  269. ret, data_len);
  270. /* blocking recv_all */
  271. n=recv_all(unix_socket, (char*)data+ret, data_len-ret, MSG_WAITALL);
  272. if (n>=0) ret+=n;
  273. else{
  274. ret=n;
  275. goto error;
  276. }
  277. }
  278. #ifdef HAVE_MSGHDR_MSG_CONTROL
  279. cmsg=CMSG_FIRSTHDR(&msg);
  280. if ((cmsg!=0) && (cmsg->cmsg_len==CMSG_LEN(sizeof(new_fd)))){
  281. if (cmsg->cmsg_type!= SCM_RIGHTS){
  282. LM_ERR("msg control type != SCM_RIGHTS\n");
  283. ret=-1;
  284. goto error;
  285. }
  286. if (cmsg->cmsg_level!= SOL_SOCKET){
  287. LM_ERR("msg level != SOL_SOCKET\n");
  288. ret=-1;
  289. goto error;
  290. }
  291. pi=(int*) CMSG_DATA(cmsg);
  292. *fd=*pi;
  293. }else{
  294. /*LM_ERR("no descriptor passed, cmsg=%p, len=%d\n",
  295. cmsg, (unsigned)cmsg->cmsg_len); */
  296. *fd=-1;
  297. /* it's not really an error */
  298. }
  299. #else
  300. if (msg.msg_accrightslen==sizeof(int)){
  301. *fd=new_fd;
  302. }else{
  303. /*LM_ERR("no descriptor passed, accrightslen=%d\n",
  304. msg.msg_accrightslen); */
  305. *fd=-1;
  306. }
  307. #endif
  308. error:
  309. return ret;
  310. }
  311. #endif