_sendmsg.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. /*
  2. * Copyright (c) Twisted Matrix Laboratories.
  3. * See LICENSE for details.
  4. */
  5. #define PY_SSIZE_T_CLEAN 1
  6. #include <Python.h>
  7. #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
  8. /* This may cause some warnings, but if you want to get rid of them, upgrade
  9. * your Python version. */
  10. typedef int Py_ssize_t;
  11. #endif
  12. #include <sys/types.h>
  13. #include <sys/socket.h>
  14. #include <signal.h>
  15. #include <sys/param.h>
  16. #ifdef BSD
  17. #include <sys/uio.h>
  18. #endif
  19. /*
  20. * As per
  21. * <http://pubs.opengroup.org/onlinepubs/007904875/basedefs/sys/socket.h.html
  22. * #tag_13_61_05>:
  23. *
  24. * "To forestall portability problems, it is recommended that applications
  25. * not use values larger than (2**31)-1 for the socklen_t type."
  26. */
  27. #define SOCKLEN_MAX 0x7FFFFFFF
  28. PyObject *sendmsg_socket_error;
  29. static PyObject *sendmsg_sendmsg(PyObject *self, PyObject *args, PyObject *keywds);
  30. static PyObject *sendmsg_recvmsg(PyObject *self, PyObject *args, PyObject *keywds);
  31. static PyObject *sendmsg_getsockfam(PyObject *self, PyObject *args, PyObject *keywds);
  32. static char sendmsg_doc[] = "\
  33. Bindings for sendmsg(2), recvmsg(2), and a minimal helper for inspecting\n\
  34. address family of a socket.\n\
  35. ";
  36. static char sendmsg_sendmsg_doc[] = "\
  37. Wrap the C sendmsg(2) function for sending \"messages\" on a socket.\n\
  38. \n\
  39. @param fd: The file descriptor of the socket over which to send a message.\n\
  40. @type fd: C{int}\n\
  41. \n\
  42. @param data: Bytes to write to the socket.\n\
  43. @type data: C{str}\n\
  44. \n\
  45. @param flags: Flags to affect how the message is sent. See the C{MSG_}\n\
  46. constants in the sendmsg(2) manual page. By default no flags are set.\n\
  47. @type flags: C{int}\n\
  48. \n\
  49. @param ancillary: Extra data to send over the socket outside of the normal\n\
  50. datagram or stream mechanism. By default no ancillary data is sent.\n\
  51. @type ancillary: C{list} of C{tuple} of C{int}, C{int}, and C{str}.\n\
  52. \n\
  53. @raise OverflowError: Raised if too much ancillary data is given.\n\
  54. @raise socket.error: Raised if the underlying syscall indicates an error.\n\
  55. \n\
  56. @return: The return value of the underlying syscall, if it succeeds.\n\
  57. ";
  58. static char sendmsg_recvmsg_doc[] = "\
  59. Wrap the C recvmsg(2) function for receiving \"messages\" on a socket.\n\
  60. \n\
  61. @param fd: The file descriptor of the socket over which to receive a message.\n\
  62. @type fd: C{int}\n\
  63. \n\
  64. @param flags: Flags to affect how the message is sent. See the C{MSG_}\n\
  65. constants in the sendmsg(2) manual page. By default no flags are set.\n\
  66. @type flags: C{int}\n\
  67. \n\
  68. @param maxsize: The maximum number of bytes to receive from the socket\n\
  69. using the datagram or stream mechanism. The default maximum is 8192.\n\
  70. @type maxsize: C{int}\n\
  71. \n\
  72. @param cmsg_size: The maximum number of bytes to receive from the socket\n\
  73. outside of the normal datagram or stream mechanism. The default maximum is 4096.\n\
  74. \n\
  75. @raise OverflowError: Raised if too much ancillary data is given.\n\
  76. @raise socket.error: Raised if the underlying syscall indicates an error.\n\
  77. \n\
  78. @return: A C{tuple} of three elements: the bytes received using the\n\
  79. datagram/stream mechanism, flags as an C{int} describing the data\n\
  80. received, and a C{list} of C{tuples} giving ancillary received data.\n\
  81. ";
  82. static char sendmsg_getsockfam_doc[] = "\
  83. Retrieve the address family of a given socket.\n\
  84. \n\
  85. @param fd: The file descriptor of the socket the address family of which\n\
  86. to retrieve.\n\
  87. @type fd: C{int}\n\
  88. \n\
  89. @raise socket.error: Raised if the underlying getsockname call indicates\n\
  90. an error.\n\
  91. \n\
  92. @return: A C{int} representing the address family of the socket. For\n\
  93. example, L{socket.AF_INET}, L{socket.AF_INET6}, or L{socket.AF_UNIX}.\n\
  94. ";
  95. static PyMethodDef sendmsg_methods[] = {
  96. {"send1msg", (PyCFunction) sendmsg_sendmsg, METH_VARARGS | METH_KEYWORDS,
  97. sendmsg_sendmsg_doc},
  98. {"recv1msg", (PyCFunction) sendmsg_recvmsg, METH_VARARGS | METH_KEYWORDS,
  99. sendmsg_recvmsg_doc},
  100. {"getsockfam", (PyCFunction) sendmsg_getsockfam,
  101. METH_VARARGS | METH_KEYWORDS, sendmsg_getsockfam_doc},
  102. {NULL, NULL, 0, NULL}
  103. };
  104. PyMODINIT_FUNC init_sendmsg(void) {
  105. PyObject *module;
  106. sendmsg_socket_error = NULL; /* Make sure that this has a known value
  107. before doing anything that might exit. */
  108. module = Py_InitModule3("_sendmsg", sendmsg_methods, sendmsg_doc);
  109. if (!module) {
  110. return;
  111. }
  112. /*
  113. The following is the only value mentioned by POSIX:
  114. http://www.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
  115. */
  116. if (-1 == PyModule_AddIntConstant(module, "SCM_RIGHTS", SCM_RIGHTS)) {
  117. return;
  118. }
  119. /* BSD, Darwin, Hurd */
  120. #if defined(SCM_CREDS)
  121. if (-1 == PyModule_AddIntConstant(module, "SCM_CREDS", SCM_CREDS)) {
  122. return;
  123. }
  124. #endif
  125. /* Linux */
  126. #if defined(SCM_CREDENTIALS)
  127. if (-1 == PyModule_AddIntConstant(module, "SCM_CREDENTIALS", SCM_CREDENTIALS)) {
  128. return;
  129. }
  130. #endif
  131. /* Apparently everywhere, but not standardized. */
  132. #if defined(SCM_TIMESTAMP)
  133. if (-1 == PyModule_AddIntConstant(module, "SCM_TIMESTAMP", SCM_TIMESTAMP)) {
  134. return;
  135. }
  136. #endif
  137. module = PyImport_ImportModule("socket");
  138. if (!module) {
  139. return;
  140. }
  141. sendmsg_socket_error = PyObject_GetAttrString(module, "error");
  142. if (!sendmsg_socket_error) {
  143. return;
  144. }
  145. }
  146. static PyObject *sendmsg_sendmsg(PyObject *self, PyObject *args, PyObject *keywds) {
  147. int fd;
  148. int flags = 0;
  149. Py_ssize_t sendmsg_result, iovec_length;
  150. struct msghdr message_header;
  151. struct iovec iov[1];
  152. PyObject *ancillary = NULL;
  153. PyObject *iterator = NULL;
  154. PyObject *item = NULL;
  155. PyObject *result_object = NULL;
  156. static char *kwlist[] = {"fd", "data", "flags", "ancillary", NULL};
  157. if (!PyArg_ParseTupleAndKeywords(
  158. args, keywds, "it#|iO:sendmsg", kwlist,
  159. &fd,
  160. &iov[0].iov_base,
  161. &iovec_length,
  162. &flags,
  163. &ancillary)) {
  164. return NULL;
  165. }
  166. iov[0].iov_len = iovec_length;
  167. message_header.msg_name = NULL;
  168. message_header.msg_namelen = 0;
  169. message_header.msg_iov = iov;
  170. message_header.msg_iovlen = 1;
  171. message_header.msg_control = NULL;
  172. message_header.msg_controllen = 0;
  173. message_header.msg_flags = 0;
  174. if (ancillary) {
  175. if (!PyList_Check(ancillary)) {
  176. PyErr_Format(PyExc_TypeError,
  177. "send1msg argument 3 expected list, got %s",
  178. ancillary->ob_type->tp_name);
  179. goto finished;
  180. }
  181. iterator = PyObject_GetIter(ancillary);
  182. if (iterator == NULL) {
  183. goto finished;
  184. }
  185. size_t all_data_len = 0;
  186. /* First we need to know how big the buffer needs to be in order to
  187. have enough space for all of the messages. */
  188. while ( (item = PyIter_Next(iterator)) ) {
  189. int type, level;
  190. Py_ssize_t data_len;
  191. size_t prev_all_data_len;
  192. char *data;
  193. if (!PyTuple_Check(item)) {
  194. PyErr_Format(PyExc_TypeError,
  195. "send1msg argument 3 expected list of tuple, "
  196. "got list containing %s",
  197. item->ob_type->tp_name);
  198. goto finished;
  199. }
  200. if (!PyArg_ParseTuple(
  201. item, "iit#:sendmsg ancillary data (level, type, data)",
  202. &level, &type, &data, &data_len)) {
  203. goto finished;
  204. }
  205. prev_all_data_len = all_data_len;
  206. all_data_len += CMSG_SPACE(data_len);
  207. Py_DECREF(item);
  208. item = NULL;
  209. if (all_data_len < prev_all_data_len) {
  210. PyErr_Format(PyExc_OverflowError,
  211. "Too much msg_control to fit in a size_t: %zu",
  212. prev_all_data_len);
  213. goto finished;
  214. }
  215. }
  216. Py_DECREF(iterator);
  217. iterator = NULL;
  218. /* Allocate the buffer for all of the ancillary elements, if we have
  219. * any. */
  220. if (all_data_len) {
  221. if (all_data_len > SOCKLEN_MAX) {
  222. PyErr_Format(PyExc_OverflowError,
  223. "Too much msg_control to fit in a socklen_t: %zu",
  224. all_data_len);
  225. goto finished;
  226. }
  227. message_header.msg_control = PyMem_Malloc(all_data_len);
  228. if (!message_header.msg_control) {
  229. PyErr_NoMemory();
  230. goto finished;
  231. }
  232. /* From Python 3.5.2 socketmodule.c:3891:
  233. Need to zero out the buffer as a workaround for glibc's
  234. CMSG_NXTHDR() implementation. After getting the pointer to
  235. the next header, it checks its (uninitialized) cmsg_len
  236. member to see if the "message" fits in the buffer, and
  237. returns NULL if it doesn't. Zero-filling the buffer
  238. ensures that this doesn't happen. */
  239. memset(message_header.msg_control, 0, all_data_len);
  240. } else {
  241. message_header.msg_control = NULL;
  242. }
  243. message_header.msg_controllen = (socklen_t) all_data_len;
  244. iterator = PyObject_GetIter(ancillary); /* again */
  245. if (!iterator) {
  246. goto finished;
  247. }
  248. /* Unpack the tuples into the control message. */
  249. struct cmsghdr *control_message = CMSG_FIRSTHDR(&message_header);
  250. while ( (item = PyIter_Next(iterator)) && control_message!=NULL ) {
  251. int type, level;
  252. Py_ssize_t data_len;
  253. size_t data_size;
  254. unsigned char *data, *cmsg_data;
  255. /* We explicitly allocated enough space for all ancillary data
  256. above; if there isn't enough room, all bets are off. */
  257. assert(control_message);
  258. if (!PyArg_ParseTuple(item,
  259. "iit#:sendmsg ancillary data (level, type, data)",
  260. &level,
  261. &type,
  262. &data,
  263. &data_len)) {
  264. goto finished;
  265. }
  266. control_message->cmsg_level = level;
  267. control_message->cmsg_type = type;
  268. data_size = CMSG_LEN(data_len);
  269. if (data_size > SOCKLEN_MAX) {
  270. PyErr_Format(PyExc_OverflowError,
  271. "CMSG_LEN(%zd) > SOCKLEN_MAX", data_len);
  272. goto finished;
  273. }
  274. control_message->cmsg_len = (socklen_t) data_size;
  275. cmsg_data = CMSG_DATA(control_message);
  276. memcpy(cmsg_data, data, data_len);
  277. Py_DECREF(item);
  278. item = NULL;
  279. control_message = CMSG_NXTHDR(&message_header, control_message);
  280. }
  281. Py_DECREF(iterator);
  282. iterator = NULL;
  283. if (PyErr_Occurred()) {
  284. goto finished;
  285. }
  286. }
  287. sendmsg_result = sendmsg(fd, &message_header, flags);
  288. if (sendmsg_result < 0) {
  289. PyErr_SetFromErrno(sendmsg_socket_error);
  290. goto finished;
  291. }
  292. result_object = Py_BuildValue("n", sendmsg_result);
  293. finished:
  294. if (item) {
  295. Py_DECREF(item);
  296. item = NULL;
  297. }
  298. if (iterator) {
  299. Py_DECREF(iterator);
  300. iterator = NULL;
  301. }
  302. if (message_header.msg_control) {
  303. PyMem_Free(message_header.msg_control);
  304. message_header.msg_control = NULL;
  305. }
  306. return result_object;
  307. }
  308. static PyObject *sendmsg_recvmsg(PyObject *self, PyObject *args, PyObject *keywds) {
  309. int fd = -1;
  310. int flags = 0;
  311. int maxsize = 8192;
  312. int cmsg_size = 4096;
  313. size_t cmsg_space;
  314. size_t cmsg_overhead;
  315. Py_ssize_t recvmsg_result;
  316. struct msghdr message_header;
  317. struct cmsghdr *control_message;
  318. struct iovec iov[1];
  319. char *cmsgbuf;
  320. PyObject *ancillary;
  321. PyObject *final_result = NULL;
  322. static char *kwlist[] = {"fd", "flags", "maxsize", "cmsg_size", NULL};
  323. if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii:recvmsg", kwlist,
  324. &fd, &flags, &maxsize, &cmsg_size)) {
  325. return NULL;
  326. }
  327. cmsg_space = CMSG_SPACE(cmsg_size);
  328. /* overflow check */
  329. if (cmsg_space > SOCKLEN_MAX) {
  330. PyErr_Format(PyExc_OverflowError,
  331. "CMSG_SPACE(cmsg_size) greater than SOCKLEN_MAX: %d",
  332. cmsg_size);
  333. return NULL;
  334. }
  335. message_header.msg_name = NULL;
  336. message_header.msg_namelen = 0;
  337. iov[0].iov_len = maxsize;
  338. iov[0].iov_base = PyMem_Malloc(maxsize);
  339. if (!iov[0].iov_base) {
  340. PyErr_NoMemory();
  341. return NULL;
  342. }
  343. message_header.msg_iov = iov;
  344. message_header.msg_iovlen = 1;
  345. cmsgbuf = PyMem_Malloc(cmsg_space);
  346. if (!cmsgbuf) {
  347. PyMem_Free(iov[0].iov_base);
  348. PyErr_NoMemory();
  349. return NULL;
  350. }
  351. memset(cmsgbuf, 0, cmsg_space);
  352. message_header.msg_control = cmsgbuf;
  353. /* see above for overflow check */
  354. message_header.msg_controllen = (socklen_t) cmsg_space;
  355. recvmsg_result = recvmsg(fd, &message_header, flags);
  356. if (recvmsg_result < 0) {
  357. PyErr_SetFromErrno(sendmsg_socket_error);
  358. goto finished;
  359. }
  360. ancillary = PyList_New(0);
  361. if (!ancillary) {
  362. goto finished;
  363. }
  364. for (control_message = CMSG_FIRSTHDR(&message_header);
  365. control_message;
  366. control_message = CMSG_NXTHDR(&message_header,
  367. control_message)) {
  368. PyObject *entry;
  369. /* Some platforms apparently always fill out the ancillary data
  370. structure with a single bogus value if none is provided; ignore it,
  371. if that is the case. */
  372. if ((!(control_message->cmsg_level)) &&
  373. (!(control_message->cmsg_type))) {
  374. continue;
  375. }
  376. /*
  377. * Figure out how much of the cmsg size is cmsg structure overhead - in
  378. * other words, how much is not part of the application data. This lets
  379. * us compute the right application data size below. There should
  380. * really be a CMSG_ macro for this.
  381. */
  382. cmsg_overhead = (char*)CMSG_DATA(control_message) - (char*)control_message;
  383. entry = Py_BuildValue(
  384. "(iis#)",
  385. control_message->cmsg_level,
  386. control_message->cmsg_type,
  387. CMSG_DATA(control_message),
  388. (Py_ssize_t) (control_message->cmsg_len - cmsg_overhead));
  389. if (!entry) {
  390. Py_DECREF(ancillary);
  391. goto finished;
  392. }
  393. if (PyList_Append(ancillary, entry) < 0) {
  394. Py_DECREF(ancillary);
  395. Py_DECREF(entry);
  396. goto finished;
  397. } else {
  398. Py_DECREF(entry);
  399. }
  400. }
  401. final_result = Py_BuildValue(
  402. "s#iO",
  403. iov[0].iov_base,
  404. recvmsg_result,
  405. message_header.msg_flags,
  406. ancillary);
  407. Py_DECREF(ancillary);
  408. finished:
  409. PyMem_Free(iov[0].iov_base);
  410. PyMem_Free(cmsgbuf);
  411. return final_result;
  412. }
  413. static PyObject *sendmsg_getsockfam(PyObject *self, PyObject *args,
  414. PyObject *keywds) {
  415. int fd;
  416. struct sockaddr sa;
  417. static char *kwlist[] = {"fd", NULL};
  418. if (!PyArg_ParseTupleAndKeywords(args, keywds, "i", kwlist, &fd)) {
  419. return NULL;
  420. }
  421. socklen_t sz = sizeof(sa);
  422. if (getsockname(fd, &sa, &sz)) {
  423. PyErr_SetFromErrno(sendmsg_socket_error);
  424. return NULL;
  425. }
  426. return Py_BuildValue("i", sa.sa_family);
  427. }