conversions.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561
  1. #include "sockaddr_conv.h"
  2. #include "conversions.h"
  3. #include "sendrecvmsg.h" /* for ancillary registry */
  4. #ifdef PHP_WIN32
  5. # include "windows_common.h"
  6. #endif
  7. #include <Zend/zend_llist.h>
  8. #include <ext/standard/php_smart_str.h>
  9. #ifndef PHP_WIN32
  10. # include <sys/types.h>
  11. # include <sys/socket.h>
  12. # include <arpa/inet.h>
  13. # include <netinet/in.h>
  14. # include <sys/un.h>
  15. # include <sys/ioctl.h>
  16. # include <net/if.h>
  17. #else
  18. # include <win32/php_stdint.h>
  19. #endif
  20. #include <limits.h>
  21. #include <stdarg.h>
  22. #include <stddef.h>
  23. #ifdef PHP_WIN32
  24. typedef unsigned short sa_family_t;
  25. # define msghdr _WSAMSG
  26. /*
  27. struct _WSAMSG {
  28. LPSOCKADDR name; //void *msg_name
  29. INT namelen; //socklen_t msg_namelen
  30. LPWSABUF lpBuffers; //struct iovec *msg_iov
  31. ULONG dwBufferCount; //size_t msg_iovlen
  32. WSABUF Control; //void *msg_control, size_t msg_controllen
  33. DWORD dwFlags; //int msg_flags
  34. }
  35. struct __WSABUF {
  36. u_long len; //size_t iov_len (2nd member)
  37. char FAR *buf; //void *iov_base (1st member)
  38. }
  39. struct _WSACMSGHDR {
  40. UINT cmsg_len; //socklen_t cmsg_len
  41. INT cmsg_level; //int cmsg_level
  42. INT cmsg_type; //int cmsg_type;
  43. followed by UCHAR cmsg_data[]
  44. }
  45. */
  46. # define msg_name name
  47. # define msg_namelen namelen
  48. # define msg_iov lpBuffers
  49. # define msg_iovlen dwBufferCount
  50. # define msg_control Control.buf
  51. # define msg_controllen Control.len
  52. # define msg_flags dwFlags
  53. # define iov_base buf
  54. # define iov_len len
  55. # define cmsghdr _WSACMSGHDR
  56. # ifdef CMSG_DATA
  57. # undef CMSG_DATA
  58. # endif
  59. # define CMSG_DATA WSA_CMSG_DATA
  60. #endif
  61. #define MAX_USER_BUFF_SIZE ((size_t)(100*1024*1024))
  62. #define DEFAULT_BUFF_SIZE 8192
  63. struct _ser_context {
  64. HashTable params; /* stores pointers; has to be first */
  65. struct err_s err;
  66. zend_llist keys,
  67. /* common part to res_context ends here */
  68. allocations;
  69. php_socket *sock;
  70. };
  71. struct _res_context {
  72. HashTable params; /* stores pointers; has to be first */
  73. struct err_s err;
  74. zend_llist keys;
  75. };
  76. typedef struct {
  77. /* zval info */
  78. const char *name;
  79. unsigned name_size;
  80. int required;
  81. /* structure info */
  82. size_t field_offset; /* 0 to pass full structure, e.g. when more than
  83. one field is to be changed; in that case the
  84. callbacks need to know the name of the fields */
  85. /* callbacks */
  86. from_zval_write_field *from_zval;
  87. to_zval_read_field *to_zval;
  88. } field_descriptor;
  89. #define KEY_FILL_SOCKADDR "fill_sockaddr"
  90. #define KEY_RECVMSG_RET "recvmsg_ret"
  91. #define KEY_CMSG_LEN "cmsg_len"
  92. const struct key_value empty_key_value_list[] = {{0}};
  93. /* PARAMETERS */
  94. static int param_get_bool(void *ctx, const char *key, int def)
  95. {
  96. int **elem;
  97. if (zend_hash_find(ctx, key, strlen(key) + 1, (void**)&elem) == SUCCESS) {
  98. return **elem;
  99. } else {
  100. return def;
  101. }
  102. }
  103. /* MEMORY */
  104. static inline void *accounted_emalloc(size_t alloc_size, ser_context *ctx)
  105. {
  106. void *ret = emalloc(alloc_size);
  107. zend_llist_add_element(&ctx->allocations, &ret);
  108. return ret;
  109. }
  110. static inline void *accounted_ecalloc(size_t nmemb, size_t alloc_size, ser_context *ctx)
  111. {
  112. void *ret = ecalloc(nmemb, alloc_size);
  113. zend_llist_add_element(&ctx->allocations, &ret);
  114. return ret;
  115. }
  116. static inline void *accounted_safe_ecalloc(size_t nmemb, size_t alloc_size, size_t offset, ser_context *ctx)
  117. {
  118. void *ret = safe_emalloc(nmemb, alloc_size, offset);
  119. memset(ret, '\0', nmemb * alloc_size + offset);
  120. zend_llist_add_element(&ctx->allocations, &ret);
  121. return ret;
  122. }
  123. /* ERRORS */
  124. static void do_from_to_zval_err(struct err_s *err,
  125. zend_llist *keys,
  126. const char *what_conv,
  127. const char *fmt,
  128. va_list ap)
  129. {
  130. smart_str path = {0};
  131. const char **node;
  132. char *user_msg;
  133. int user_msg_size;
  134. zend_llist_position pos;
  135. if (err->has_error) {
  136. return;
  137. }
  138. for (node = zend_llist_get_first_ex(keys, &pos);
  139. node != NULL;
  140. node = zend_llist_get_next_ex(keys, &pos)) {
  141. smart_str_appends(&path, *node);
  142. smart_str_appends(&path, " > ");
  143. }
  144. if (path.len > 3) {
  145. path.len -= 3;
  146. }
  147. smart_str_0(&path);
  148. user_msg_size = vspprintf(&user_msg, 0, fmt, ap);
  149. err->has_error = 1;
  150. err->level = E_WARNING;
  151. spprintf(&err->msg, 0, "error converting %s data (path: %s): %.*s",
  152. what_conv,
  153. path.c && path.c != '\0' ? path.c : "unavailable",
  154. user_msg_size, user_msg);
  155. err->should_free = 1;
  156. efree(user_msg);
  157. smart_str_free_ex(&path, 0);
  158. }
  159. ZEND_ATTRIBUTE_FORMAT(printf, 2 ,3)
  160. static void do_from_zval_err(ser_context *ctx, const char *fmt, ...)
  161. {
  162. va_list ap;
  163. va_start(ap, fmt);
  164. do_from_to_zval_err(&ctx->err, &ctx->keys, "user", fmt, ap);
  165. va_end(ap);
  166. }
  167. ZEND_ATTRIBUTE_FORMAT(printf, 2 ,3)
  168. static void do_to_zval_err(res_context *ctx, const char *fmt, ...)
  169. {
  170. va_list ap;
  171. va_start(ap, fmt);
  172. do_from_to_zval_err(&ctx->err, &ctx->keys, "native", fmt, ap);
  173. va_end(ap);
  174. }
  175. void err_msg_dispose(struct err_s *err TSRMLS_DC)
  176. {
  177. if (err->msg != NULL) {
  178. php_error_docref0(NULL TSRMLS_CC, err->level, "%s", err->msg);
  179. if (err->should_free) {
  180. efree(err->msg);
  181. }
  182. }
  183. }
  184. void allocations_dispose(zend_llist **allocations)
  185. {
  186. zend_llist_destroy(*allocations);
  187. efree(*allocations);
  188. *allocations = NULL;
  189. }
  190. static unsigned from_array_iterate(const zval *arr,
  191. void (*func)(zval **elem, unsigned i, void **args, ser_context *ctx),
  192. void **args,
  193. ser_context *ctx)
  194. {
  195. HashPosition pos;
  196. unsigned i;
  197. zval **elem;
  198. char buf[sizeof("element #4294967295")];
  199. char *bufp = buf;
  200. /* Note i starts at 1, not 0! */
  201. for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 1;
  202. !ctx->err.has_error
  203. && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
  204. zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos), i++) {
  205. if (snprintf(buf, sizeof(buf), "element #%u", i) >= sizeof(buf)) {
  206. memcpy(buf, "element", sizeof("element"));
  207. }
  208. zend_llist_add_element(&ctx->keys, &bufp);
  209. func(elem, i, args, ctx);
  210. zend_llist_remove_tail(&ctx->keys);
  211. }
  212. return i -1;
  213. }
  214. /* Generic Aggregated conversions */
  215. static void from_zval_write_aggregation(const zval *container,
  216. char *structure,
  217. const field_descriptor *descriptors,
  218. ser_context *ctx)
  219. {
  220. const field_descriptor *descr;
  221. zval **elem;
  222. if (Z_TYPE_P(container) != IS_ARRAY) {
  223. do_from_zval_err(ctx, "%s", "expected an array here");
  224. }
  225. for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
  226. if (zend_hash_find(Z_ARRVAL_P(container),
  227. descr->name, descr->name_size, (void**)&elem) == SUCCESS) {
  228. if (descr->from_zval == NULL) {
  229. do_from_zval_err(ctx, "No information on how to convert value "
  230. "of key '%s'", descr->name);
  231. break;
  232. }
  233. zend_llist_add_element(&ctx->keys, (void*)&descr->name);
  234. descr->from_zval(*elem, ((char*)structure) + descr->field_offset, ctx);
  235. zend_llist_remove_tail(&ctx->keys);
  236. } else if (descr->required) {
  237. do_from_zval_err(ctx, "The key '%s' is required", descr->name);
  238. break;
  239. }
  240. }
  241. }
  242. static void to_zval_read_aggregation(const char *structure,
  243. zval *zarr, /* initialized array */
  244. const field_descriptor *descriptors,
  245. res_context *ctx)
  246. {
  247. const field_descriptor *descr;
  248. assert(Z_TYPE_P(zarr) == IS_ARRAY);
  249. assert(Z_ARRVAL_P(zarr) != NULL);
  250. for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
  251. zval *new_zv;
  252. if (descr->to_zval == NULL) {
  253. do_to_zval_err(ctx, "No information on how to convert native "
  254. "field into value for key '%s'", descr->name);
  255. break;
  256. }
  257. ALLOC_INIT_ZVAL(new_zv);
  258. add_assoc_zval_ex(zarr, descr->name, descr->name_size, new_zv);
  259. zend_llist_add_element(&ctx->keys, (void*)&descr->name);
  260. descr->to_zval(structure + descr->field_offset, new_zv, ctx);
  261. zend_llist_remove_tail(&ctx->keys);
  262. }
  263. }
  264. /* CONVERSIONS for integers */
  265. static long from_zval_integer_common(const zval *arr_value, ser_context *ctx)
  266. {
  267. long ret = 0;
  268. zval lzval = zval_used_for_init;
  269. if (Z_TYPE_P(arr_value) != IS_LONG) {
  270. ZVAL_COPY_VALUE(&lzval, arr_value);
  271. zval_copy_ctor(&lzval);
  272. arr_value = &lzval;
  273. }
  274. switch (Z_TYPE_P(arr_value)) {
  275. case IS_LONG:
  276. long_case:
  277. ret = Z_LVAL_P(arr_value);
  278. break;
  279. /* if not long we're operating on lzval */
  280. case IS_DOUBLE:
  281. double_case:
  282. convert_to_long(&lzval);
  283. goto long_case;
  284. case IS_OBJECT:
  285. case IS_STRING: {
  286. long lval;
  287. double dval;
  288. convert_to_string(&lzval);
  289. switch (is_numeric_string(Z_STRVAL(lzval), Z_STRLEN(lzval), &lval, &dval, 0)) {
  290. case IS_DOUBLE:
  291. zval_dtor(&lzval);
  292. Z_TYPE(lzval) = IS_DOUBLE;
  293. Z_DVAL(lzval) = dval;
  294. goto double_case;
  295. case IS_LONG:
  296. zval_dtor(&lzval);
  297. Z_TYPE(lzval) = IS_LONG;
  298. Z_LVAL(lzval) = lval;
  299. goto long_case;
  300. }
  301. /* if we get here, we don't have a numeric string */
  302. do_from_zval_err(ctx, "expected an integer, but got a non numeric "
  303. "string (possibly from a converted object): '%s'", Z_STRVAL_P(arr_value));
  304. break;
  305. }
  306. default:
  307. do_from_zval_err(ctx, "%s", "expected an integer, either of a PHP "
  308. "integer type or of a convertible type");
  309. break;
  310. }
  311. zval_dtor(&lzval);
  312. return ret;
  313. }
  314. void from_zval_write_int(const zval *arr_value, char *field, ser_context *ctx)
  315. {
  316. long lval;
  317. int ival;
  318. lval = from_zval_integer_common(arr_value, ctx);
  319. if (ctx->err.has_error) {
  320. return;
  321. }
  322. if (lval > INT_MAX || lval < INT_MIN) {
  323. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  324. "for a native int");
  325. return;
  326. }
  327. ival = (int)lval;
  328. memcpy(field, &ival, sizeof(ival));
  329. }
  330. static void from_zval_write_uint32(const zval *arr_value, char *field, ser_context *ctx)
  331. {
  332. long lval;
  333. uint32_t ival;
  334. lval = from_zval_integer_common(arr_value, ctx);
  335. if (ctx->err.has_error) {
  336. return;
  337. }
  338. if (sizeof(long) > sizeof(uint32_t) && (lval < 0 || lval > 0xFFFFFFFF)) {
  339. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  340. "for an unsigned 32-bit integer");
  341. return;
  342. }
  343. ival = (uint32_t)lval;
  344. memcpy(field, &ival, sizeof(ival));
  345. }
  346. static void from_zval_write_net_uint16(const zval *arr_value, char *field, ser_context *ctx)
  347. {
  348. long lval;
  349. uint16_t ival;
  350. lval = from_zval_integer_common(arr_value, ctx);
  351. if (ctx->err.has_error) {
  352. return;
  353. }
  354. if (lval < 0 || lval > 0xFFFF) {
  355. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  356. "for an unsigned 16-bit integer");
  357. return;
  358. }
  359. ival = htons((uint16_t)lval);
  360. memcpy(field, &ival, sizeof(ival));
  361. }
  362. static void from_zval_write_sa_family(const zval *arr_value, char *field, ser_context *ctx)
  363. {
  364. long lval;
  365. sa_family_t ival;
  366. lval = from_zval_integer_common(arr_value, ctx);
  367. if (ctx->err.has_error) {
  368. return;
  369. }
  370. if (lval < 0 || lval > (sa_family_t)-1) { /* sa_family_t is unsigned */
  371. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  372. "for a sa_family_t value");
  373. return;
  374. }
  375. ival = (sa_family_t)lval;
  376. memcpy(field, &ival, sizeof(ival));
  377. }
  378. static void from_zval_write_pid_t(const zval *arr_value, char *field, ser_context *ctx)
  379. {
  380. long lval;
  381. pid_t ival;
  382. lval = from_zval_integer_common(arr_value, ctx);
  383. if (ctx->err.has_error) {
  384. return;
  385. }
  386. if (lval < 0 || (pid_t)lval != lval) { /* pid_t is signed */
  387. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  388. "for a pid_t value");
  389. return;
  390. }
  391. ival = (pid_t)lval;
  392. memcpy(field, &ival, sizeof(ival));
  393. }
  394. static void from_zval_write_uid_t(const zval *arr_value, char *field, ser_context *ctx)
  395. {
  396. long lval;
  397. uid_t ival;
  398. lval = from_zval_integer_common(arr_value, ctx);
  399. if (ctx->err.has_error) {
  400. return;
  401. }
  402. /* uid_t can be signed or unsigned (generally unsigned) */
  403. if ((uid_t)-1 > (uid_t)0) {
  404. if (sizeof(long) > sizeof(uid_t) && (lval < 0 || (uid_t)lval != lval)) {
  405. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  406. "for a uid_t value");
  407. return;
  408. }
  409. } else {
  410. if (sizeof(long) > sizeof(uid_t) && (uid_t)lval != lval) {
  411. do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
  412. "for a uid_t value");
  413. return;
  414. }
  415. }
  416. ival = (uid_t)lval;
  417. memcpy(field, &ival, sizeof(ival));
  418. }
  419. void to_zval_read_int(const char *data, zval *zv, res_context *ctx)
  420. {
  421. int ival;
  422. memcpy(&ival, data, sizeof(ival));
  423. ZVAL_LONG(zv, (long)ival);
  424. }
  425. static void to_zval_read_unsigned(const char *data, zval *zv, res_context *ctx)
  426. {
  427. unsigned ival;
  428. memcpy(&ival, data, sizeof(ival));
  429. ZVAL_LONG(zv, (long)ival);
  430. }
  431. static void to_zval_read_net_uint16(const char *data, zval *zv, res_context *ctx)
  432. {
  433. uint16_t ival;
  434. memcpy(&ival, data, sizeof(ival));
  435. ZVAL_LONG(zv, (long)ntohs(ival));
  436. }
  437. static void to_zval_read_uint32(const char *data, zval *zv, res_context *ctx)
  438. {
  439. uint32_t ival;
  440. memcpy(&ival, data, sizeof(ival));
  441. ZVAL_LONG(zv, (long)ival);
  442. }
  443. static void to_zval_read_sa_family(const char *data, zval *zv, res_context *ctx)
  444. {
  445. sa_family_t ival;
  446. memcpy(&ival, data, sizeof(ival));
  447. ZVAL_LONG(zv, (long)ival);
  448. }
  449. static void to_zval_read_pid_t(const char *data, zval *zv, res_context *ctx)
  450. {
  451. pid_t ival;
  452. memcpy(&ival, data, sizeof(ival));
  453. ZVAL_LONG(zv, (long)ival);
  454. }
  455. static void to_zval_read_uid_t(const char *data, zval *zv, res_context *ctx)
  456. {
  457. uid_t ival;
  458. memcpy(&ival, data, sizeof(ival));
  459. ZVAL_LONG(zv, (long)ival);
  460. }
  461. /* CONVERSIONS for sockaddr */
  462. static void from_zval_write_sin_addr(const zval *zaddr_str, char *inaddr, ser_context *ctx)
  463. {
  464. int res;
  465. struct sockaddr_in saddr = {0};
  466. zval lzval = zval_used_for_init;
  467. TSRMLS_FETCH();
  468. if (Z_TYPE_P(zaddr_str) != IS_STRING) {
  469. ZVAL_COPY_VALUE(&lzval, zaddr_str);
  470. zval_copy_ctor(&lzval);
  471. convert_to_string(&lzval);
  472. zaddr_str = &lzval;
  473. }
  474. res = php_set_inet_addr(&saddr, Z_STRVAL_P(zaddr_str), ctx->sock TSRMLS_CC);
  475. if (res) {
  476. memcpy(inaddr, &saddr.sin_addr, sizeof saddr.sin_addr);
  477. } else {
  478. /* error already emitted, but let's emit another more relevant */
  479. do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET "
  480. "address", Z_STRVAL_P(zaddr_str));
  481. }
  482. zval_dtor(&lzval);
  483. }
  484. static void to_zval_read_sin_addr(const char *data, zval *zv, res_context *ctx)
  485. {
  486. const struct in_addr *addr = (const struct in_addr *)data;
  487. socklen_t size = INET_ADDRSTRLEN;
  488. Z_TYPE_P(zv) = IS_STRING;
  489. Z_STRVAL_P(zv) = ecalloc(1, size);
  490. Z_STRLEN_P(zv) = 0;
  491. if (inet_ntop(AF_INET, addr, Z_STRVAL_P(zv), size) == NULL) {
  492. do_to_zval_err(ctx, "could not convert IPv4 address to string "
  493. "(errno %d)", errno);
  494. return;
  495. }
  496. Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv));
  497. }
  498. static const field_descriptor descriptors_sockaddr_in[] = {
  499. {"family", sizeof("family"), 0, offsetof(struct sockaddr_in, sin_family), from_zval_write_sa_family, to_zval_read_sa_family},
  500. {"addr", sizeof("addr"), 0, offsetof(struct sockaddr_in, sin_addr), from_zval_write_sin_addr, to_zval_read_sin_addr},
  501. {"port", sizeof("port"), 0, offsetof(struct sockaddr_in, sin_port), from_zval_write_net_uint16, to_zval_read_net_uint16},
  502. {0}
  503. };
  504. static void from_zval_write_sockaddr_in(const zval *container, char *sockaddr, ser_context *ctx)
  505. {
  506. from_zval_write_aggregation(container, sockaddr, descriptors_sockaddr_in, ctx);
  507. }
  508. static void to_zval_read_sockaddr_in(const char *data, zval *zv, res_context *ctx)
  509. {
  510. to_zval_read_aggregation(data, zv, descriptors_sockaddr_in, ctx);
  511. }
  512. #if HAVE_IPV6
  513. static void from_zval_write_sin6_addr(const zval *zaddr_str, char *addr6, ser_context *ctx)
  514. {
  515. int res;
  516. struct sockaddr_in6 saddr6 = {0};
  517. zval lzval = zval_used_for_init;
  518. TSRMLS_FETCH();
  519. if (Z_TYPE_P(zaddr_str) != IS_STRING) {
  520. ZVAL_COPY_VALUE(&lzval, zaddr_str);
  521. zval_copy_ctor(&lzval);
  522. convert_to_string(&lzval);
  523. zaddr_str = &lzval;
  524. }
  525. res = php_set_inet6_addr(&saddr6,
  526. Z_STRVAL_P(zaddr_str), ctx->sock TSRMLS_CC);
  527. if (res) {
  528. memcpy(addr6, &saddr6.sin6_addr, sizeof saddr6.sin6_addr);
  529. } else {
  530. /* error already emitted, but let's emit another more relevant */
  531. do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET6 "
  532. "address", Z_STRVAL_P(zaddr_str));
  533. }
  534. zval_dtor(&lzval);
  535. }
  536. static void to_zval_read_sin6_addr(const char *data, zval *zv, res_context *ctx)
  537. {
  538. const struct in6_addr *addr = (const struct in6_addr *)data;
  539. socklen_t size = INET6_ADDRSTRLEN;
  540. Z_TYPE_P(zv) = IS_STRING;
  541. Z_STRVAL_P(zv) = ecalloc(1, size);
  542. Z_STRLEN_P(zv) = 0;
  543. if (inet_ntop(AF_INET6, addr, Z_STRVAL_P(zv), size) == NULL) {
  544. do_to_zval_err(ctx, "could not convert IPv6 address to string "
  545. "(errno %d)", errno);
  546. return;
  547. }
  548. Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv));
  549. }
  550. static const field_descriptor descriptors_sockaddr_in6[] = {
  551. {"family", sizeof("family"), 0, offsetof(struct sockaddr_in6, sin6_family), from_zval_write_sa_family, to_zval_read_sa_family},
  552. {"addr", sizeof("addr"), 0, offsetof(struct sockaddr_in6, sin6_addr), from_zval_write_sin6_addr, to_zval_read_sin6_addr},
  553. {"port", sizeof("port"), 0, offsetof(struct sockaddr_in6, sin6_port), from_zval_write_net_uint16, to_zval_read_net_uint16},
  554. {"flowinfo", sizeof("flowinfo"), 0, offsetof(struct sockaddr_in6, sin6_flowinfo), from_zval_write_uint32, to_zval_read_uint32},
  555. {"scope_id", sizeof("scope_id"), 0, offsetof(struct sockaddr_in6, sin6_scope_id), from_zval_write_uint32, to_zval_read_uint32},
  556. {0}
  557. };
  558. static void from_zval_write_sockaddr_in6(const zval *container, char *sockaddr6, ser_context *ctx)
  559. {
  560. from_zval_write_aggregation(container, sockaddr6, descriptors_sockaddr_in6, ctx);
  561. }
  562. static void to_zval_read_sockaddr_in6(const char *data, zval *zv, res_context *ctx)
  563. {
  564. to_zval_read_aggregation(data, zv, descriptors_sockaddr_in6, ctx);
  565. }
  566. #endif /* HAVE_IPV6 */
  567. static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_context *ctx)
  568. {
  569. zval lzval = zval_used_for_init;
  570. struct sockaddr_un *saddr = (struct sockaddr_un*)sockaddr_un_c;
  571. if (Z_TYPE_P(path) != IS_STRING) {
  572. ZVAL_COPY_VALUE(&lzval, path);
  573. zval_copy_ctor(&lzval);
  574. convert_to_string(&lzval);
  575. path = &lzval;
  576. }
  577. /* code in this file relies on the path being nul terminated, even though
  578. * this is not required, at least on linux for abstract paths. It also
  579. * assumes that the path is not empty */
  580. if (Z_STRLEN_P(path) == 0) {
  581. do_from_zval_err(ctx, "%s", "the path is cannot be empty");
  582. return;
  583. }
  584. if (Z_STRLEN_P(path) >= sizeof(saddr->sun_path)) {
  585. do_from_zval_err(ctx, "the path is too long, the maximum permitted "
  586. "length is %ld", sizeof(saddr->sun_path) - 1);
  587. return;
  588. }
  589. memcpy(&saddr->sun_path, Z_STRVAL_P(path), Z_STRLEN_P(path));
  590. saddr->sun_path[Z_STRLEN_P(path)] = '\0';
  591. zval_dtor(&lzval);
  592. }
  593. static void to_zval_read_sun_path(const char *data, zval *zv, res_context *ctx) {
  594. struct sockaddr_un *saddr = (struct sockaddr_un*)data;
  595. char *nul_pos;
  596. nul_pos = memchr(&saddr->sun_path, '\0', sizeof(saddr->sun_path));
  597. if (nul_pos == NULL) {
  598. do_to_zval_err(ctx, "could not find a NUL in the path");
  599. return;
  600. }
  601. ZVAL_STRINGL(zv, saddr->sun_path, nul_pos - (char*)&saddr->sun_path, 1);
  602. }
  603. static const field_descriptor descriptors_sockaddr_un[] = {
  604. {"family", sizeof("family"), 0, offsetof(struct sockaddr_un, sun_family), from_zval_write_sa_family, to_zval_read_sa_family},
  605. {"path", sizeof("path"), 0, 0, from_zval_write_sun_path, to_zval_read_sun_path},
  606. {0}
  607. };
  608. static void from_zval_write_sockaddr_un(const zval *container, char *sockaddr, ser_context *ctx)
  609. {
  610. from_zval_write_aggregation(container, sockaddr, descriptors_sockaddr_un, ctx);
  611. }
  612. static void to_zval_read_sockaddr_un(const char *data, zval *zv, res_context *ctx)
  613. {
  614. to_zval_read_aggregation(data, zv, descriptors_sockaddr_un, ctx);
  615. }
  616. static void from_zval_write_sockaddr_aux(const zval *container,
  617. struct sockaddr **sockaddr_ptr,
  618. socklen_t *sockaddr_len,
  619. ser_context *ctx)
  620. {
  621. int family;
  622. zval **elem;
  623. int fill_sockaddr;
  624. if (Z_TYPE_P(container) != IS_ARRAY) {
  625. do_from_zval_err(ctx, "%s", "expected an array here");
  626. return;
  627. }
  628. fill_sockaddr = param_get_bool(ctx, KEY_FILL_SOCKADDR, 1);
  629. if (zend_hash_find(Z_ARRVAL_P(container), "family", sizeof("family"), (void**)&elem) == SUCCESS
  630. && Z_TYPE_PP(elem) != IS_NULL) {
  631. const char *node = "family";
  632. zend_llist_add_element(&ctx->keys, &node);
  633. from_zval_write_int(*elem, (char*)&family, ctx);
  634. zend_llist_remove_tail(&ctx->keys);
  635. } else {
  636. family = ctx->sock->type;
  637. }
  638. switch (family) {
  639. case AF_INET:
  640. /* though not all OSes support sockaddr_in used in IPv6 sockets */
  641. if (ctx->sock->type != AF_INET && ctx->sock->type != AF_INET6) {
  642. do_from_zval_err(ctx, "the specified family (number %d) is not "
  643. "supported on this socket", family);
  644. return;
  645. }
  646. *sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_in), ctx);
  647. *sockaddr_len = sizeof(struct sockaddr_in);
  648. if (fill_sockaddr) {
  649. from_zval_write_sockaddr_in(container, (char*)*sockaddr_ptr, ctx);
  650. (*sockaddr_ptr)->sa_family = AF_INET;
  651. }
  652. break;
  653. #if HAVE_IPV6
  654. case AF_INET6:
  655. if (ctx->sock->type != AF_INET6) {
  656. do_from_zval_err(ctx, "the specified family (AF_INET6) is not "
  657. "supported on this socket");
  658. return;
  659. }
  660. *sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_in6), ctx);
  661. *sockaddr_len = sizeof(struct sockaddr_in6);
  662. if (fill_sockaddr) {
  663. from_zval_write_sockaddr_in6(container, (char*)*sockaddr_ptr, ctx);
  664. (*sockaddr_ptr)->sa_family = AF_INET6;
  665. }
  666. break;
  667. #endif /* HAVE_IPV6 */
  668. case AF_UNIX:
  669. if (ctx->sock->type != AF_UNIX) {
  670. do_from_zval_err(ctx, "the specified family (AF_UNIX) is not "
  671. "supported on this socket");
  672. return;
  673. }
  674. *sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_un), ctx);
  675. if (fill_sockaddr) {
  676. struct sockaddr_un *sock_un = (struct sockaddr_un*)*sockaddr_ptr;
  677. from_zval_write_sockaddr_un(container, (char*)*sockaddr_ptr, ctx);
  678. (*sockaddr_ptr)->sa_family = AF_UNIX;
  679. /* calculating length is more complicated here. Giving the size of
  680. * struct sockaddr_un here and relying on the nul termination of
  681. * sun_path does not work for paths in the abstract namespace. Note
  682. * that we always assume the path is not empty and nul terminated */
  683. *sockaddr_len = offsetof(struct sockaddr_un, sun_path) +
  684. (sock_un->sun_path[0] == '\0'
  685. ? (1 + strlen(&sock_un->sun_path[1]))
  686. : strlen(sock_un->sun_path));
  687. } else {
  688. *sockaddr_len = sizeof(struct sockaddr_un);
  689. }
  690. break;
  691. default:
  692. do_from_zval_err(ctx, "%s", "the only families currently supported are "
  693. "AF_INET, AF_INET6 and AF_UNIX");
  694. break;
  695. }
  696. }
  697. static void to_zval_read_sockaddr_aux(const char *sockaddr_c, zval *zv, res_context *ctx)
  698. {
  699. const struct sockaddr *saddr = (struct sockaddr *)sockaddr_c;
  700. if (saddr->sa_family == 0) {
  701. ZVAL_NULL(zv);
  702. return;
  703. }
  704. array_init(zv);
  705. switch (saddr->sa_family) {
  706. case AF_INET:
  707. to_zval_read_sockaddr_in(sockaddr_c, zv, ctx);
  708. break;
  709. #if HAVE_IPV6
  710. case AF_INET6:
  711. to_zval_read_sockaddr_in6(sockaddr_c, zv, ctx);
  712. break;
  713. #endif /* HAVE_IPV6 */
  714. case AF_UNIX:
  715. to_zval_read_sockaddr_un(sockaddr_c, zv, ctx);
  716. break;
  717. default:
  718. do_to_zval_err(ctx, "cannot read struct sockaddr with family %d; "
  719. "not supported",
  720. (int)saddr->sa_family);
  721. break;
  722. }
  723. }
  724. /* CONVERSIONS for cmsghdr */
  725. /*
  726. * [ level => , type => , data => [],]
  727. * struct cmsghdr {
  728. * socklen_t cmsg_len; // data byte count, including header
  729. * int cmsg_level; // originating protocol
  730. * int cmsg_type; // protocol-specific type
  731. * // followed by unsigned char cmsg_data[];
  732. * };
  733. */
  734. static void from_zval_write_control(const zval *arr,
  735. void **control_buf,
  736. zend_llist_element *alloc,
  737. size_t *control_len,
  738. size_t *offset,
  739. ser_context *ctx)
  740. {
  741. struct cmsghdr *cmsghdr;
  742. int level,
  743. type;
  744. size_t data_len,
  745. req_space,
  746. space_left;
  747. ancillary_reg_entry *entry;
  748. static const field_descriptor descriptor_level[] = {
  749. {"level", sizeof("level"), 0, 0, from_zval_write_int, 0},
  750. {0}
  751. };
  752. static const field_descriptor descriptor_type[] = {
  753. {"type", sizeof("type"), 0, 0, from_zval_write_int, 0},
  754. {0}
  755. };
  756. field_descriptor descriptor_data[] = {
  757. {"data", sizeof("data"), 0, 0, 0, 0},
  758. {0}
  759. };
  760. from_zval_write_aggregation(arr, (char *)&level, descriptor_level, ctx);
  761. if (ctx->err.has_error) {
  762. return;
  763. }
  764. from_zval_write_aggregation(arr, (char *)&type, descriptor_type, ctx);
  765. if (ctx->err.has_error) {
  766. return;
  767. }
  768. entry = get_ancillary_reg_entry(level, type);
  769. if (entry == NULL) {
  770. do_from_zval_err(ctx, "cmsghdr with level %d and type %d not supported",
  771. level, type);
  772. return;
  773. }
  774. if (entry->calc_space) {
  775. zval **data_elem;
  776. /* arr must be an array at this point */
  777. if (zend_hash_find(Z_ARRVAL_P(arr), "data", sizeof("data"),
  778. (void**)&data_elem) == FAILURE) {
  779. do_from_zval_err(ctx, "cmsghdr should have a 'data' element here");
  780. return;
  781. }
  782. data_len = entry->calc_space(*data_elem, ctx);
  783. if (ctx->err.has_error) {
  784. return;
  785. }
  786. } else {
  787. data_len = entry->size;
  788. }
  789. req_space = CMSG_SPACE(data_len);
  790. space_left = *control_len - *offset;
  791. assert(*control_len >= *offset);
  792. if (space_left < req_space) {
  793. *control_buf = safe_erealloc(*control_buf, 2, req_space, *control_len);
  794. *control_len += 2 * req_space;
  795. memset((char *)*control_buf + *offset, '\0', *control_len - *offset);
  796. memcpy(&alloc->data, control_buf, sizeof *control_buf);
  797. }
  798. cmsghdr = (struct cmsghdr*)(((char*)*control_buf) + *offset);
  799. cmsghdr->cmsg_level = level;
  800. cmsghdr->cmsg_type = type;
  801. cmsghdr->cmsg_len = CMSG_LEN(data_len);
  802. descriptor_data[0].from_zval = entry->from_array;
  803. from_zval_write_aggregation(arr, (char*)CMSG_DATA(cmsghdr), descriptor_data, ctx);
  804. *offset += req_space;
  805. }
  806. static void from_zval_write_control_array(const zval *arr, char *msghdr_c, ser_context *ctx)
  807. {
  808. HashPosition pos;
  809. char buf[sizeof("element #4294967295")];
  810. char *bufp = buf;
  811. zval **elem;
  812. uint32_t i;
  813. int num_elems;
  814. void *control_buf;
  815. zend_llist_element *alloc;
  816. size_t control_len,
  817. cur_offset;
  818. struct msghdr *msg = (struct msghdr*)msghdr_c;
  819. if (Z_TYPE_P(arr) != IS_ARRAY) {
  820. do_from_zval_err(ctx, "%s", "expected an array here");
  821. return;
  822. }
  823. num_elems = zend_hash_num_elements(Z_ARRVAL_P(arr));
  824. if (num_elems == 0) {
  825. return;
  826. }
  827. /* estimate each message at 20 bytes */
  828. control_buf = accounted_safe_ecalloc(num_elems, CMSG_SPACE(20), 0, ctx);
  829. alloc = ctx->allocations.tail;
  830. control_len = (size_t)num_elems * CMSG_SPACE(20);
  831. cur_offset = 0;
  832. for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 0;
  833. !ctx->err.has_error
  834. && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
  835. zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos)) {
  836. if (snprintf(buf, sizeof(buf), "element #%u", (unsigned)i++) >= sizeof(buf)) {
  837. memcpy(buf, "element", sizeof("element"));
  838. }
  839. zend_llist_add_element(&ctx->keys, &bufp);
  840. from_zval_write_control(*elem, &control_buf, alloc, &control_len,
  841. &cur_offset, ctx);
  842. zend_llist_remove_tail(&ctx->keys);
  843. }
  844. msg->msg_control = control_buf;
  845. msg->msg_controllen = cur_offset; /* not control_len, which may be larger */
  846. }
  847. static void to_zval_read_cmsg_data(const char *cmsghdr_c, zval *zv, res_context *ctx)
  848. {
  849. const struct cmsghdr *cmsg = (const struct cmsghdr *)cmsghdr_c;
  850. ancillary_reg_entry *entry;
  851. size_t len,
  852. *len_p = &len;
  853. entry = get_ancillary_reg_entry(cmsg->cmsg_level, cmsg->cmsg_type);
  854. if (entry == NULL) {
  855. do_to_zval_err(ctx, "cmsghdr with level %d and type %d not supported",
  856. cmsg->cmsg_level, cmsg->cmsg_type);
  857. return;
  858. }
  859. if (CMSG_LEN(entry->size) > cmsg->cmsg_len) {
  860. do_to_zval_err(ctx, "the cmsghdr structure is unexpectedly small; "
  861. "expected a length of at least %ld, but got %ld",
  862. (long)CMSG_LEN(entry->size), (long)cmsg->cmsg_len);
  863. return;
  864. }
  865. len = (size_t)cmsg->cmsg_len; /* use another var because type of cmsg_len varies */
  866. if (zend_hash_add(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN),
  867. &len_p, sizeof(len_p), NULL) == FAILURE) {
  868. do_to_zval_err(ctx, "%s", "could not set parameter " KEY_CMSG_LEN);
  869. return;
  870. }
  871. entry->to_array((const char *)CMSG_DATA(cmsg), zv, ctx);
  872. zend_hash_del(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN));
  873. }
  874. static void to_zval_read_control(const char *cmsghdr_c, zval *zv, res_context *ctx)
  875. {
  876. /* takes a cmsghdr, not a msghdr like from_zval_write_control */
  877. static const field_descriptor descriptors[] = {
  878. {"level", sizeof("level"), 0, offsetof(struct cmsghdr, cmsg_level), 0, to_zval_read_int},
  879. {"type", sizeof("type"), 0, offsetof(struct cmsghdr, cmsg_type), 0, to_zval_read_int},
  880. {"data", sizeof("data"), 0, 0 /* cmsghdr passed */, 0, to_zval_read_cmsg_data},
  881. {0}
  882. };
  883. array_init_size(zv, 3);
  884. to_zval_read_aggregation(cmsghdr_c, zv, descriptors, ctx);
  885. }
  886. static void to_zval_read_control_array(const char *msghdr_c, zval *zv, res_context *ctx)
  887. {
  888. struct msghdr *msg = (struct msghdr *)msghdr_c;
  889. struct cmsghdr *cmsg;
  890. char buf[sizeof("element #4294967295")];
  891. char *bufp = buf;
  892. uint32_t i = 1;
  893. /*if (msg->msg_flags & MSG_CTRUNC) {
  894. php_error_docref0(NULL, E_WARNING, "The MSG_CTRUNC flag is present; will not "
  895. "attempt to read control messages");
  896. ZVAL_FALSE(zv);
  897. return;
  898. }*/
  899. array_init(zv);
  900. for (cmsg = CMSG_FIRSTHDR(msg);
  901. cmsg != NULL && !ctx->err.has_error;
  902. cmsg = CMSG_NXTHDR(msg, cmsg)) {
  903. zval *elem;
  904. ALLOC_INIT_ZVAL(elem);
  905. add_next_index_zval(zv, elem);
  906. if (snprintf(buf, sizeof(buf), "element #%u", (unsigned)i++) >= sizeof(buf)) {
  907. memcpy(buf, "element", sizeof("element"));
  908. }
  909. zend_llist_add_element(&ctx->keys, &bufp);
  910. to_zval_read_control((const char *)cmsg, elem, ctx);
  911. zend_llist_remove_tail(&ctx->keys);
  912. }
  913. }
  914. /* CONVERSIONS for msghdr */
  915. static void from_zval_write_name(const zval *zname_arr, char *msghdr_c, ser_context *ctx)
  916. {
  917. struct sockaddr *sockaddr;
  918. socklen_t sockaddr_len;
  919. struct msghdr *msghdr = (struct msghdr *)msghdr_c;
  920. from_zval_write_sockaddr_aux(zname_arr, &sockaddr, &sockaddr_len, ctx);
  921. msghdr->msg_name = sockaddr;
  922. msghdr->msg_namelen = sockaddr_len;
  923. }
  924. static void to_zval_read_name(const char *sockaddr_p, zval *zv, res_context *ctx)
  925. {
  926. void *name = (void*)*(void**)sockaddr_p;
  927. if (name == NULL) {
  928. ZVAL_NULL(zv);
  929. } else {
  930. to_zval_read_sockaddr_aux(name, zv, ctx);
  931. }
  932. }
  933. static void from_zval_write_msghdr_buffer_size(const zval *elem, char *msghdr_c, ser_context *ctx)
  934. {
  935. long lval;
  936. struct msghdr *msghdr = (struct msghdr *)msghdr_c;
  937. lval = from_zval_integer_common(elem, ctx);
  938. if (ctx->err.has_error) {
  939. return;
  940. }
  941. if (lval < 0 || lval > MAX_USER_BUFF_SIZE) {
  942. do_from_zval_err(ctx, "the buffer size must be between 1 and %ld; "
  943. "given %ld", (long)MAX_USER_BUFF_SIZE, lval);
  944. return;
  945. }
  946. msghdr->msg_iovlen = 1;
  947. msghdr->msg_iov = accounted_emalloc(sizeof(*msghdr->msg_iov) * 1, ctx);
  948. msghdr->msg_iov[0].iov_base = accounted_emalloc((size_t)lval, ctx);
  949. msghdr->msg_iov[0].iov_len = (size_t)lval;
  950. }
  951. static void from_zval_write_iov_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
  952. {
  953. struct msghdr *msg = args[0];
  954. size_t len;
  955. zval_add_ref(elem);
  956. convert_to_string_ex(elem);
  957. len = Z_STRLEN_PP(elem);
  958. msg->msg_iov[i - 1].iov_base = accounted_emalloc(len, ctx);
  959. msg->msg_iov[i - 1].iov_len = len;
  960. memcpy(msg->msg_iov[i - 1].iov_base, Z_STRVAL_PP(elem), len);
  961. zval_ptr_dtor(elem);
  962. }
  963. static void from_zval_write_iov_array(const zval *arr, char *msghdr_c, ser_context *ctx)
  964. {
  965. int num_elem;
  966. struct msghdr *msg = (struct msghdr*)msghdr_c;
  967. if (Z_TYPE_P(arr) != IS_ARRAY) {
  968. do_from_zval_err(ctx, "%s", "expected an array here");
  969. return;
  970. }
  971. num_elem = zend_hash_num_elements(Z_ARRVAL_P(arr));
  972. if (num_elem == 0) {
  973. return;
  974. }
  975. msg->msg_iov = accounted_safe_ecalloc(num_elem, sizeof *msg->msg_iov, 0, ctx);
  976. msg->msg_iovlen = (size_t)num_elem;
  977. from_array_iterate(arr, from_zval_write_iov_array_aux, (void**)&msg, ctx);
  978. }
  979. static void from_zval_write_controllen(const zval *elem, char *msghdr_c, ser_context *ctx)
  980. {
  981. struct msghdr *msghdr = (struct msghdr *)msghdr_c;
  982. uint32_t len;
  983. /* controllen should be an unsigned with at least 32-bit. Let's assume
  984. * this least common denominator
  985. */
  986. from_zval_write_uint32(elem, (char*)&len, ctx);
  987. if (!ctx->err.has_error && len == 0) {
  988. do_from_zval_err(ctx, "controllen cannot be 0");
  989. return;
  990. }
  991. msghdr->msg_control = accounted_emalloc(len, ctx);
  992. msghdr->msg_controllen = len;
  993. }
  994. void from_zval_write_msghdr_send(const zval *container, char *msghdr_c, ser_context *ctx)
  995. {
  996. static const field_descriptor descriptors[] = {
  997. {"name", sizeof("name"), 0, 0, from_zval_write_name, 0},
  998. {"iov", sizeof("iov"), 0, 0, from_zval_write_iov_array, 0},
  999. {"control", sizeof("control"), 0, 0, from_zval_write_control_array, 0},
  1000. {0}
  1001. };
  1002. from_zval_write_aggregation(container, msghdr_c, descriptors, ctx);
  1003. }
  1004. void from_zval_write_msghdr_recv(const zval *container, char *msghdr_c, ser_context *ctx)
  1005. {
  1006. /* zval to struct msghdr, version for recvmsg(). It differs from the version
  1007. * for sendmsg() in that it:
  1008. * - has a buffer_size instead of an iov array;
  1009. * - has no control element; has a controllen element instead
  1010. * struct msghdr {
  1011. * void *msg_name;
  1012. * socklen_t msg_namelen;
  1013. * struct iovec *msg_iov;
  1014. * size_t msg_iovlen;
  1015. * void *msg_control;
  1016. * size_t msg_controllen; //can also be socklen_t
  1017. * int msg_flags;
  1018. * };
  1019. */
  1020. static const field_descriptor descriptors[] = {
  1021. {"name", sizeof("name"), 0, 0, from_zval_write_name, 0},
  1022. {"buffer_size", sizeof("buffer_size"), 0, 0, from_zval_write_msghdr_buffer_size, 0},
  1023. {"controllen", sizeof("controllen"), 1, 0, from_zval_write_controllen, 0},
  1024. {0}
  1025. };
  1026. struct msghdr *msghdr = (struct msghdr *)msghdr_c;
  1027. const int falsev = 0,
  1028. *falsevp = &falsev;
  1029. if (zend_hash_add(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR),
  1030. (void*)&falsevp, sizeof(falsevp), NULL) == FAILURE) {
  1031. do_from_zval_err(ctx, "could not add fill_sockaddr; this is a bug");
  1032. return;
  1033. }
  1034. from_zval_write_aggregation(container, msghdr_c, descriptors, ctx);
  1035. zend_hash_del(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR));
  1036. if (ctx->err.has_error) {
  1037. return;
  1038. }
  1039. if (msghdr->msg_iovlen == 0) {
  1040. msghdr->msg_iovlen = 1;
  1041. msghdr->msg_iov = accounted_emalloc(sizeof(*msghdr->msg_iov) * 1, ctx);
  1042. msghdr->msg_iov[0].iov_base = accounted_emalloc((size_t)DEFAULT_BUFF_SIZE, ctx);
  1043. msghdr->msg_iov[0].iov_len = (size_t)DEFAULT_BUFF_SIZE;
  1044. }
  1045. }
  1046. static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx)
  1047. {
  1048. const struct msghdr *msghdr = (const struct msghdr *)msghdr_c;
  1049. size_t iovlen = msghdr->msg_iovlen;
  1050. ssize_t **recvmsg_ret,
  1051. bytes_left;
  1052. uint i;
  1053. if (iovlen > UINT_MAX) {
  1054. do_to_zval_err(ctx, "unexpectedly large value for iov_len: %lu",
  1055. (unsigned long)iovlen);
  1056. }
  1057. array_init_size(zv, (uint)iovlen);
  1058. if (zend_hash_find(&ctx->params, KEY_RECVMSG_RET, sizeof(KEY_RECVMSG_RET),
  1059. (void**)&recvmsg_ret) == FAILURE) {
  1060. do_to_zval_err(ctx, "recvmsg_ret not found in params. This is a bug");
  1061. return;
  1062. }
  1063. bytes_left = **recvmsg_ret;
  1064. for (i = 0; bytes_left > 0 && i < (uint)iovlen; i++) {
  1065. zval *elem;
  1066. size_t len = MIN(msghdr->msg_iov[i].iov_len, (size_t)bytes_left);
  1067. char *buf = safe_emalloc(1, len, 1);
  1068. MAKE_STD_ZVAL(elem);
  1069. memcpy(buf, msghdr->msg_iov[i].iov_base, len);
  1070. buf[len] = '\0';
  1071. ZVAL_STRINGL(elem, buf, len, 0);
  1072. add_next_index_zval(zv, elem);
  1073. bytes_left -= len;
  1074. }
  1075. }
  1076. void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx)
  1077. {
  1078. static const field_descriptor descriptors[] = {
  1079. {"name", sizeof("name"), 0, offsetof(struct msghdr, msg_name), 0, to_zval_read_name},
  1080. {"control", sizeof("control"), 0, 0, 0, to_zval_read_control_array},
  1081. {"iov", sizeof("iov"), 0, 0, 0, to_zval_read_iov},
  1082. {"flags", sizeof("flags"), 0, offsetof(struct msghdr, msg_flags), 0, to_zval_read_int},
  1083. {0}
  1084. };
  1085. array_init_size(zv, 4);
  1086. to_zval_read_aggregation(msghdr_c, zv, descriptors, ctx);
  1087. }
  1088. /* CONVERSIONS for if_index */
  1089. static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context *ctx)
  1090. {
  1091. unsigned ret = 0;
  1092. zval lzval = zval_used_for_init;
  1093. if (Z_TYPE_P(zv) == IS_LONG) {
  1094. if (Z_LVAL_P(zv) < 0 || Z_LVAL_P(zv) > UINT_MAX) { /* allow 0 (unspecified interface) */
  1095. do_from_zval_err(ctx, "the interface index cannot be negative or "
  1096. "larger than %u; given %ld", UINT_MAX, Z_LVAL_P(zv));
  1097. } else {
  1098. ret = (unsigned)Z_LVAL_P(zv);
  1099. }
  1100. } else {
  1101. if (Z_TYPE_P(zv) != IS_STRING) {
  1102. ZVAL_COPY_VALUE(&lzval, zv);
  1103. zval_copy_ctor(&lzval);
  1104. convert_to_string(&lzval);
  1105. zv = &lzval;
  1106. }
  1107. #if HAVE_IF_NAMETOINDEX
  1108. ret = if_nametoindex(Z_STRVAL_P(zv));
  1109. if (ret == 0) {
  1110. do_from_zval_err(ctx, "no interface with name \"%s\" could be "
  1111. "found", Z_STRVAL_P(zv));
  1112. }
  1113. #elif defined(SIOCGIFINDEX)
  1114. {
  1115. struct ifreq ifr;
  1116. if (strlcpy(ifr.ifr_name, Z_STRVAL_P(zv), sizeof(ifr.ifr_name))
  1117. >= sizeof(ifr.ifr_name)) {
  1118. do_from_zval_err(ctx, "the interface name \"%s\" is too large ",
  1119. Z_STRVAL_P(zv));
  1120. } else if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) {
  1121. if (errno == ENODEV) {
  1122. do_from_zval_err(ctx, "no interface with name \"%s\" could be "
  1123. "found", Z_STRVAL_P(zv));
  1124. } else {
  1125. do_from_zval_err(ctx, "error fetching interface index for "
  1126. "interface with name \"%s\" (errno %d)",
  1127. Z_STRVAL_P(zv), errno);
  1128. }
  1129. } else {
  1130. ret = (unsigned)ifr.ifr_ifindex;
  1131. }
  1132. }
  1133. #else
  1134. do_from_zval_err(ctx,
  1135. "this platform does not support looking up an interface by "
  1136. "name, an integer interface index must be supplied instead");
  1137. #endif
  1138. }
  1139. if (!ctx->err.has_error) {
  1140. memcpy(uinteger, &ret, sizeof(ret));
  1141. }
  1142. zval_dtor(&lzval);
  1143. }
  1144. /* CONVERSIONS for struct in6_pktinfo */
  1145. #if defined(IPV6_PKTINFO) && HAVE_IPV6
  1146. static const field_descriptor descriptors_in6_pktinfo[] = {
  1147. {"addr", sizeof("addr"), 1, offsetof(struct in6_pktinfo, ipi6_addr), from_zval_write_sin6_addr, to_zval_read_sin6_addr},
  1148. {"ifindex", sizeof("ifindex"), 1, offsetof(struct in6_pktinfo, ipi6_ifindex), from_zval_write_ifindex, to_zval_read_unsigned},
  1149. {0}
  1150. };
  1151. void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser_context *ctx)
  1152. {
  1153. from_zval_write_aggregation(container, in6_pktinfo_c, descriptors_in6_pktinfo, ctx);
  1154. }
  1155. void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx)
  1156. {
  1157. array_init_size(zv, 2);
  1158. to_zval_read_aggregation(data, zv, descriptors_in6_pktinfo, ctx);
  1159. }
  1160. #endif
  1161. /* CONVERSIONS for struct ucred */
  1162. #ifdef SO_PASSCRED
  1163. static const field_descriptor descriptors_ucred[] = {
  1164. {"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t},
  1165. {"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t},
  1166. /* assume the type gid_t is the same as uid_t: */
  1167. {"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t},
  1168. {0}
  1169. };
  1170. void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx)
  1171. {
  1172. from_zval_write_aggregation(container, ucred_c, descriptors_ucred, ctx);
  1173. }
  1174. void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx)
  1175. {
  1176. array_init_size(zv, 3);
  1177. to_zval_read_aggregation(data, zv, descriptors_ucred, ctx);
  1178. }
  1179. #endif
  1180. /* CONVERSIONS for SCM_RIGHTS */
  1181. #ifdef SCM_RIGHTS
  1182. size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx)
  1183. {
  1184. int num_elems;
  1185. if (Z_TYPE_P(arr) != IS_ARRAY) {
  1186. do_from_zval_err(ctx, "%s", "expected an array here");
  1187. return (size_t)-1;
  1188. }
  1189. num_elems = zend_hash_num_elements(Z_ARRVAL_P(arr));
  1190. if (num_elems == 0) {
  1191. do_from_zval_err(ctx, "%s", "expected at least one element in this array");
  1192. return (size_t)-1;
  1193. }
  1194. return zend_hash_num_elements(Z_ARRVAL_P(arr)) * sizeof(int);
  1195. }
  1196. static void from_zval_write_fd_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
  1197. {
  1198. int *iarr = args[0];
  1199. TSRMLS_FETCH();
  1200. if (Z_TYPE_PP(elem) == IS_RESOURCE) {
  1201. php_stream *stream;
  1202. php_socket *sock;
  1203. ZEND_FETCH_RESOURCE_NO_RETURN(sock, php_socket *, elem, -1,
  1204. NULL, php_sockets_le_socket());
  1205. if (sock) {
  1206. iarr[i] = sock->bsd_socket;
  1207. return;
  1208. }
  1209. ZEND_FETCH_RESOURCE2_NO_RETURN(stream, php_stream *, elem, -1,
  1210. NULL, php_file_le_stream(), php_file_le_pstream());
  1211. if (stream == NULL) {
  1212. do_from_zval_err(ctx, "resource is not a stream or a socket");
  1213. return;
  1214. }
  1215. if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1],
  1216. REPORT_ERRORS) == FAILURE) {
  1217. do_from_zval_err(ctx, "cast stream to file descriptor failed");
  1218. return;
  1219. }
  1220. } else {
  1221. do_from_zval_err(ctx, "expected a resource variable");
  1222. }
  1223. }
  1224. void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx)
  1225. {
  1226. if (Z_TYPE_P(arr) != IS_ARRAY) {
  1227. do_from_zval_err(ctx, "%s", "expected an array here");
  1228. return;
  1229. }
  1230. from_array_iterate(arr, &from_zval_write_fd_array_aux, (void**)&int_arr, ctx);
  1231. }
  1232. void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
  1233. {
  1234. size_t **cmsg_len;
  1235. int num_elems,
  1236. i;
  1237. struct cmsghdr *dummy_cmsg = 0;
  1238. size_t data_offset;
  1239. TSRMLS_FETCH();
  1240. data_offset = (unsigned char *)CMSG_DATA(dummy_cmsg)
  1241. - (unsigned char *)dummy_cmsg;
  1242. if (zend_hash_find(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN),
  1243. (void **)&cmsg_len) == FAILURE) {
  1244. do_to_zval_err(ctx, "could not get value of parameter " KEY_CMSG_LEN);
  1245. return;
  1246. }
  1247. if (**cmsg_len < data_offset) {
  1248. do_to_zval_err(ctx, "length of cmsg is smaller than its data member "
  1249. "offset (%ld vs %ld)", (long)**cmsg_len, (long)data_offset);
  1250. return;
  1251. }
  1252. num_elems = (**cmsg_len - data_offset) / sizeof(int);
  1253. array_init_size(zv, num_elems);
  1254. for (i = 0; i < num_elems; i++) {
  1255. zval *elem;
  1256. int fd;
  1257. struct stat statbuf;
  1258. MAKE_STD_ZVAL(elem);
  1259. fd = *((int *)data + i);
  1260. /* determine whether we have a socket */
  1261. if (fstat(fd, &statbuf) == -1) {
  1262. do_to_zval_err(ctx, "error creating resource for received file "
  1263. "descriptor %d: fstat() call failed with errno %d", fd, errno);
  1264. efree(elem);
  1265. return;
  1266. }
  1267. if (S_ISSOCK(statbuf.st_mode)) {
  1268. php_socket *sock = socket_import_file_descriptor(fd TSRMLS_CC);
  1269. zend_register_resource(elem, sock, php_sockets_le_socket() TSRMLS_CC);
  1270. } else {
  1271. php_stream *stream = php_stream_fopen_from_fd(fd, "rw", NULL);
  1272. php_stream_to_zval(stream, elem);
  1273. }
  1274. add_next_index_zval(zv, elem);
  1275. }
  1276. }
  1277. #endif
  1278. /* ENTRY POINT for conversions */
  1279. static void free_from_zval_allocation(void *alloc_ptr_ptr)
  1280. {
  1281. efree(*(void**)alloc_ptr_ptr);
  1282. }
  1283. void *from_zval_run_conversions(const zval *container,
  1284. php_socket *sock,
  1285. from_zval_write_field *writer,
  1286. size_t struct_size,
  1287. const char *top_name,
  1288. zend_llist **allocations /* out */,
  1289. struct err_s *err /* in/out */)
  1290. {
  1291. ser_context ctx = {{0}};
  1292. char *structure = NULL;
  1293. *allocations = NULL;
  1294. if (err->has_error) {
  1295. return NULL;
  1296. }
  1297. zend_hash_init(&ctx.params, 8, NULL, NULL, 0);
  1298. zend_llist_init(&ctx.keys, sizeof(const char *), NULL, 0);
  1299. zend_llist_init(&ctx.allocations, sizeof(void *), &free_from_zval_allocation, 0);
  1300. ctx.sock = sock;
  1301. structure = ecalloc(1, struct_size);
  1302. zend_llist_add_element(&ctx.keys, &top_name);
  1303. zend_llist_add_element(&ctx.allocations, &structure);
  1304. /* main call */
  1305. writer(container, structure, &ctx);
  1306. if (ctx.err.has_error) {
  1307. zend_llist_destroy(&ctx.allocations); /* deallocates structure as well */
  1308. structure = NULL;
  1309. *err = ctx.err;
  1310. } else {
  1311. *allocations = emalloc(sizeof **allocations);
  1312. **allocations = ctx.allocations;
  1313. }
  1314. zend_llist_destroy(&ctx.keys);
  1315. zend_hash_destroy(&ctx.params);
  1316. return structure;
  1317. }
  1318. zval *to_zval_run_conversions(const char *structure,
  1319. to_zval_read_field *reader,
  1320. const char *top_name,
  1321. const struct key_value *key_value_pairs,
  1322. struct err_s *err)
  1323. {
  1324. res_context ctx = {{0}, {0}};
  1325. const struct key_value *kv;
  1326. zval *zv = NULL;
  1327. if (err->has_error) {
  1328. return NULL;
  1329. }
  1330. ALLOC_INIT_ZVAL(zv);
  1331. zend_llist_init(&ctx.keys, sizeof(const char *), NULL, 0);
  1332. zend_llist_add_element(&ctx.keys, &top_name);
  1333. zend_hash_init(&ctx.params, 8, NULL, NULL, 0);
  1334. for (kv = key_value_pairs; kv->key != NULL; kv++) {
  1335. zend_hash_update(&ctx.params, kv->key, kv->key_size,
  1336. (void*)&kv->value, sizeof(kv->value), NULL);
  1337. }
  1338. /* main call */
  1339. reader(structure, zv, &ctx);
  1340. if (ctx.err.has_error) {
  1341. zval_ptr_dtor(&zv);
  1342. zv = NULL;
  1343. *err = ctx.err;
  1344. }
  1345. zend_llist_destroy(&ctx.keys);
  1346. zend_hash_destroy(&ctx.params);
  1347. return zv;
  1348. }