Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

541 lines
12 KiB

  1. .\" $OpenBSD: imsg_init.3,v 1.4 2011/03/05 15:05:39 claudio Exp $
  2. .\"
  3. .\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org>
  4. .\"
  5. .\" Permission to use, copy, modify, and distribute this software for any
  6. .\" purpose with or without fee is hereby granted, provided that the above
  7. .\" copyright notice and this permission notice appear in all copies.
  8. .\"
  9. .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. .\" WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
  14. .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  15. .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. .\"
  17. .Dd $Mdocdate: March 5 2011 $
  18. .Dt IMSG_INIT 3
  19. .Os
  20. .Sh NAME
  21. .Nm imsg_init ,
  22. .Nm imsg_read ,
  23. .Nm imsg_get ,
  24. .Nm imsg_compose ,
  25. .Nm imsg_composev ,
  26. .Nm imsg_create ,
  27. .Nm imsg_add ,
  28. .Nm imsg_close ,
  29. .Nm imsg_free ,
  30. .Nm imsg_flush ,
  31. .Nm imsg_clear ,
  32. .Nm ibuf_open ,
  33. .Nm ibuf_dynamic ,
  34. .Nm ibuf_add ,
  35. .Nm ibuf_reserve ,
  36. .Nm ibuf_seek ,
  37. .Nm ibuf_size ,
  38. .Nm ibuf_left ,
  39. .Nm ibuf_close ,
  40. .Nm ibuf_write ,
  41. .Nm ibuf_free ,
  42. .Nm msgbuf_init ,
  43. .Nm msgbuf_clear ,
  44. .Nm msgbuf_write ,
  45. .Nm msgbuf_drain
  46. .Nd IPC messaging functions
  47. .Sh SYNOPSIS
  48. .Fd #include <sys/types.h>
  49. .Fd #include <sys/queue.h>
  50. .Fd #include <sys/uio.h>
  51. .Fd #include <imsg.h>
  52. .Ft void
  53. .Fn imsg_init "struct imsgbuf *ibuf" "int fd"
  54. .Ft ssize_t
  55. .Fn imsg_read "struct imsgbuf *ibuf"
  56. .Ft size_t
  57. .Fn imsg_get "struct imsgbuf *ibuf" "struct imsg *imsg"
  58. .Ft int
  59. .Fn imsg_compose "struct imsgbuf *ibuf" "u_int32_t type" "uint32_t peerid" \
  60. "pid_t pid" "int fd" "void *data" "u_int16_t datalen"
  61. .Ft int
  62. .Fn imsg_composev "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \
  63. "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt"
  64. .Ft "struct ibuf *"
  65. .Fn imsg_create "struct imsgbuf *ibuf" "u_int32_t type" "u_int32_t peerid" \
  66. "pid_t pid" "u_int16_t datalen"
  67. .Ft int
  68. .Fn imsg_add "struct ibuf *buf" "void *data" "u_int16_t datalen"
  69. .Ft void
  70. .Fn imsg_close "struct imsgbuf *ibuf" "struct ibuf *msg"
  71. .Ft void
  72. .Fn imsg_free "struct imsg *imsg"
  73. .Ft int
  74. .Fn imsg_flush "struct imsgbuf *ibuf"
  75. .Ft void
  76. .Fn imsg_clear "struct imsgbuf *ibuf"
  77. .Ft "struct ibuf *"
  78. .Fn ibuf_open "size_t len"
  79. .Ft "struct ibuf *"
  80. .Fn ibuf_dynamic "size_t len" "size_t max"
  81. .Ft int
  82. .Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len"
  83. .Ft "void *"
  84. .Fn ibuf_reserve "struct ibuf *buf" "size_t len"
  85. .Ft "void *"
  86. .Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len"
  87. .Ft size_t
  88. .Fn ibuf_size "struct ibuf *buf"
  89. .Ft size_t
  90. .Fn ibuf_left "struct ibuf *buf"
  91. .Ft void
  92. .Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf"
  93. .Ft int
  94. .Fn ibuf_write "struct msgbuf *msgbuf"
  95. .Ft void
  96. .Fn ibuf_free "struct ibuf *buf"
  97. .Ft void
  98. .Fn msgbuf_init "struct msgbuf *msgbuf"
  99. .Ft void
  100. .Fn msgbuf_clear "struct msgbuf *msgbuf"
  101. .Ft int
  102. .Fn msgbuf_write "struct msgbuf *msgbuf"
  103. .Ft void
  104. .Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n"
  105. .Sh DESCRIPTION
  106. The
  107. .Nm imsg
  108. functions provide a simple mechanism for communication between processes
  109. using sockets.
  110. Each transmitted message is guaranteed to be presented to the receiving program
  111. whole.
  112. They are commonly used in privilege separated processes, where processes with
  113. different rights are required to cooperate.
  114. .Pp
  115. A program using these functions should be linked with
  116. .Em -lutil .
  117. .Pp
  118. The basic
  119. .Nm
  120. structure is the
  121. .Em imsgbuf ,
  122. which wraps a file descriptor and represents one side of a channel on which
  123. messages are sent and received:
  124. .Bd -literal -offset indent
  125. struct imsgbuf {
  126. TAILQ_HEAD(, imsg_fd) fds;
  127. struct ibuf_read r;
  128. struct msgbuf w;
  129. int fd;
  130. pid_t pid;
  131. };
  132. .Ed
  133. .Pp
  134. .Fn imsg_init
  135. is a routine which initializes
  136. .Fa ibuf
  137. as one side of a channel associated with
  138. .Fa fd .
  139. The file descriptor is used to send and receive messages,
  140. but is not closed by any of the imsg functions.
  141. An imsgbuf is initialized with the
  142. .Em w
  143. member as the output buffer queue,
  144. .Em fd
  145. with the file descriptor passed to
  146. .Fn imsg_init
  147. and the other members for internal use only.
  148. .Pp
  149. The
  150. .Fn imsg_clear
  151. function frees any data allocated as part of an imsgbuf.
  152. .Pp
  153. .Fn imsg_create ,
  154. .Fn imsg_add
  155. and
  156. .Fn imsg_close
  157. are generic construction routines for messages that are to be sent using an
  158. imsgbuf.
  159. .Pp
  160. .Fn imsg_create
  161. creates a new message with header specified by
  162. .Fa type ,
  163. .Fa peerid
  164. ands
  165. .Fa pid .
  166. A
  167. .Fa pid
  168. of zero uses the process ID returned by
  169. .Xr getpid 2
  170. when
  171. .Fa ibuf
  172. was initialized.
  173. In addition to this common imsg header,
  174. .Fa datalen
  175. bytes of space may be reserved for attaching to this imsg.
  176. This space is populated using
  177. .Fn imsg_add .
  178. Additionally, the file descriptor
  179. .Fa fd
  180. may be passed over the socket to the other process.
  181. If
  182. .Fa fd
  183. is given, it is closed in the sending program after the message is sent.
  184. A value of \-1 indicates no file descriptor should be passed.
  185. .Fn imsg_create
  186. returns a pointer to a new message if it succeeds, NULL otherwise.
  187. .Pp
  188. .Fn imsg_add
  189. appends to
  190. .Fa imsg
  191. .Fa len
  192. bytes of ancillary data pointed to by
  193. .Fa buf .
  194. It returns
  195. .Fa len
  196. if it succeeds, \-1 otherwise.
  197. .Pp
  198. .Fn imsg_close
  199. completes creation of
  200. .Fa imsg
  201. by adding it to
  202. .Fa imsgbuf
  203. output buffer.
  204. .Pp
  205. .Fn imsg_compose
  206. is a routine which is used to quickly create and queue an imsg.
  207. It takes the same parameters as the
  208. .Fn imsg_create ,
  209. .Fn imsg_add
  210. and
  211. .Fn imsg_close
  212. routines,
  213. except that only one ancillary data buffer can be provided.
  214. This routine returns 1 if it succeeds, \-1 otherwise.
  215. .Pp
  216. .Fn imsg_composev
  217. is similar to
  218. .Fn imsg_compose .
  219. It takes the same parameters, except that the ancillary data buffer is specified
  220. by
  221. .Fa iovec .
  222. .Pp
  223. .Fn imsg_flush
  224. is a function which calls
  225. .Fn msgbuf_write
  226. in a loop until all imsgs in the output buffer are sent.
  227. It returns 0 if it succeeds, \-1 otherwise.
  228. .Pp
  229. The
  230. .Fn imsg_read
  231. routine reads pending data with
  232. .Xr recvmsg 2
  233. and queues it as individual messages on
  234. .Fa imsgbuf .
  235. It returns the number of bytes read on success, or \-1 on error.
  236. A return value of \-1 from
  237. .Fn imsg_read
  238. invalidates
  239. .Fa imsgbuf ,
  240. and renders it suitable only for passing to
  241. .Fn imsg_clear .
  242. .Pp
  243. .Fn imsg_get
  244. fills in an individual imsg pending on
  245. .Fa imsgbuf
  246. into the structure pointed to by
  247. .Fa imsg .
  248. It returns the total size of the message, 0 if no messages are ready, or \-1
  249. for an error.
  250. Received messages are returned as a
  251. .Em struct imsg ,
  252. which must be freed by
  253. .Fn imsg_free
  254. when no longer required.
  255. .Em struct imsg
  256. has this form:
  257. .Bd -literal -offset indent
  258. struct imsg {
  259. struct imsg_hdr hdr;
  260. int fd;
  261. void *data;
  262. };
  263. struct imsg_hdr {
  264. u_int32_t type;
  265. u_int16_t len;
  266. u_int16_t flags;
  267. u_int32_t peerid;
  268. u_int32_t pid;
  269. };
  270. .Ed
  271. .Pp
  272. The header members are:
  273. .Bl -tag -width Ds -offset indent
  274. .It type
  275. A integer identifier, typically used to express the meaning of the message.
  276. .It len
  277. The total length of the imsg, including the header and any ancillary data
  278. transmitted with the message (pointed to by the
  279. .Em data
  280. member of the message itself).
  281. .It flags
  282. Flags used internally by the imsg functions: should not be used by application
  283. programs.
  284. .It peerid, pid
  285. 32-bit values specified on message creation and free for any use by the
  286. caller, normally used to identify the message sender.
  287. .El
  288. .Pp
  289. In addition,
  290. .Em struct imsg
  291. has the following:
  292. .Bl -tag -width Ds -offset indent
  293. .It fd
  294. The file descriptor specified when the message was created and passed using the
  295. socket control message API, or \-1 if no file descriptor was sent.
  296. .It data
  297. A pointer to the ancillary data transmitted with the imsg.
  298. .El
  299. .Pp
  300. The IMSG_HEADER_SIZE define is the size of the imsg message header, which
  301. may be subtracted from the
  302. .Fa len
  303. member of
  304. .Em struct imsg_hdr
  305. to obtain the length of any additional data passed with the message.
  306. .Pp
  307. MAX_IMSGSIZE is defined as the maximum size of a single imsg, currently
  308. 16384 bytes.
  309. .Sh BUFFERS
  310. The imsg API defines functions to manipulate buffers, used internally and during
  311. construction of imsgs with
  312. .Fn imsg_create .
  313. A
  314. .Em struct ibuf
  315. is a single buffer and a
  316. .Em struct msgbuf
  317. a queue of output buffers for transmission:
  318. .Bd -literal -offset indent
  319. struct ibuf {
  320. TAILQ_ENTRY(buf) entry;
  321. u_char *buf;
  322. size_t size;
  323. size_t max;
  324. size_t wpos;
  325. size_t rpos;
  326. int fd;
  327. };
  328. struct msgbuf {
  329. TAILQ_HEAD(, buf) bufs;
  330. u_int32_t queued;
  331. int fd;
  332. };
  333. .Ed
  334. .Pp
  335. The
  336. .Fn ibuf_open
  337. function allocates a fixed-length buffer.
  338. The buffer may not be resized and may contain a maximum of
  339. .Fa len
  340. bytes.
  341. On success
  342. .Fn ibuf_open
  343. returns a pointer to the buffer; on failure it returns NULL.
  344. .Pp
  345. .Fn ibuf_dynamic
  346. allocates a resizeable buffer of initial length
  347. .Fa len
  348. and maximum size
  349. .Fa max .
  350. Buffers allocated with
  351. .Fn ibuf_dynamic
  352. are automatically grown if necessary when data is added.
  353. .Pp
  354. .Fn ibuf_add
  355. is a routine which appends a block of data to
  356. .Fa buf .
  357. 0 is returned on success and \-1 on failure.
  358. .Pp
  359. .Fn ibuf_reserve
  360. is used to reserve
  361. .Fa len
  362. bytes in
  363. .Fa buf .
  364. A pointer to the start of the reserved space is returned, or NULL on error.
  365. .Pp
  366. .Fn ibuf_seek
  367. is a function which returns a pointer to the part of the buffer at offset
  368. .Fa pos
  369. and of extent
  370. .Fa len .
  371. NULL is returned if the requested range is outside the part of the buffer
  372. in use.
  373. .Pp
  374. .Fn ibuf_size
  375. and
  376. .Fn ibuf_left
  377. are functions which return the total bytes used and available in
  378. .Fa buf
  379. respectively.
  380. .Pp
  381. .Fn ibuf_close
  382. appends
  383. .Fa buf
  384. to
  385. .Fa msgbuf
  386. ready to be sent.
  387. .Pp
  388. The
  389. .Fn ibuf_write
  390. routine transmits as many pending buffers as possible from
  391. .Fn msgbuf
  392. using
  393. .Xr writev 2 .
  394. It returns 0 if it succeeds, \-1 on error and \-2 when an EOF condition on the
  395. socket is detected.
  396. .Pp
  397. .Fn ibuf_free
  398. frees
  399. .Fa buf
  400. and any associated storage.
  401. .Pp
  402. The
  403. .Fn msgbuf_init
  404. function initializes
  405. .Fa msgbuf
  406. so that buffers may be appended to it.
  407. The
  408. .Em fd
  409. member should also be set directly before
  410. .Fn msgbuf_write
  411. is used.
  412. .Pp
  413. .Fn msgbuf_clear
  414. empties a msgbuf, removing and discarding any queued buffers.
  415. .Pp
  416. The
  417. .Fn msgbuf_write
  418. routine calls
  419. .Xr sendmsg 2
  420. to transmit buffers queued in
  421. .Fa msgbuf .
  422. It returns 0 if it succeeds, \-1 on error, or \-2 when an EOF condition on the
  423. socket is detected.
  424. .Pp
  425. .Fn msgbuf_drain
  426. discards data from buffers queued in
  427. .Fa msgbuf
  428. until
  429. .Fa n
  430. bytes have been removed or
  431. .Fa msgbuf
  432. is empty.
  433. .Sh EXAMPLES
  434. In a typical program, a channel between two processes is created with
  435. .Xr socketpair 2 ,
  436. and an
  437. .Em imsgbuf
  438. created around one file descriptor in each process:
  439. .Bd -literal -offset indent
  440. struct imsgbuf parent_ibuf, child_ibuf;
  441. int imsg_fds[2];
  442. if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
  443. err(1, "socketpair");
  444. switch (fork()) {
  445. case -1:
  446. err(1, "fork");
  447. case 0:
  448. /* child */
  449. close(imsg_fds[0]);
  450. imsg_init(&child_ibuf, imsg_fds[1]);
  451. exit(child_main(&child_ibuf));
  452. }
  453. /* parent */
  454. close(imsg_fds[1]);
  455. imsg_init(&parent_ibuf, imsg_fds[0]);
  456. exit(parent_main(&parent_ibuf));
  457. .Ed
  458. .Pp
  459. Messages may then be composed and queued on the
  460. .Em imsgbuf ,
  461. for example using the
  462. .Fn imsg_compose
  463. function:
  464. .Bd -literal -offset indent
  465. enum imsg_type {
  466. IMSG_A_MESSAGE,
  467. IMSG_MESSAGE2
  468. }
  469. int
  470. child_main(struct imsgbuf *ibuf)
  471. {
  472. int idata;
  473. ...
  474. idata = 42;
  475. imsg_compose(ibuf, IMSG_A_MESSAGE,
  476. 0, 0, -1, &idata, sizeof idata);
  477. ...
  478. }
  479. .Ed
  480. .Pp
  481. A mechanism such as
  482. .Xr poll 2
  483. or the
  484. .Xr event 3
  485. library is used to monitor the socket file descriptor.
  486. When the socket is ready for writing, queued messages are transmitted with
  487. .Fn msgbuf_write :
  488. .Bd -literal -offset indent
  489. if (msgbuf_write(&ibuf-\*(Gtw) \*(Lt 0) {
  490. /* handle write failure */
  491. }
  492. .Ed
  493. .Pp
  494. And when ready for reading, messages are first received using
  495. .Fn imsg_read
  496. and then extracted with
  497. .Fn imsg_get :
  498. .Bd -literal -offset indent
  499. void
  500. dispatch_imsg(struct imsgbuf *ibuf)
  501. {
  502. struct imsg imsg;
  503. ssize_t n, datalen;
  504. int idata;
  505. if ((n = imsg_read(ibuf)) == -1 || n == 0) {
  506. /* handle socket error */
  507. }
  508. for (;;) {
  509. if ((n = imsg_get(ibuf, &imsg)) == -1) {
  510. /* handle read error */
  511. }
  512. if (n == 0) /* no more messages */
  513. return;
  514. datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
  515. switch (imsg.hdr.type) {
  516. case IMSG_A_MESSAGE:
  517. if (datalen \*(Lt sizeof idata) {
  518. /* handle corrupt message */
  519. }
  520. memcpy(&idata, imsg.data, sizeof idata);
  521. /* handle message received */
  522. break;
  523. ...
  524. }
  525. imsg_free(&imsg);
  526. }
  527. }
  528. .Ed
  529. .Sh SEE ALSO
  530. .Xr socketpair 2 ,
  531. .Xr unix 4