PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/sys/kern/uipc_socket.c

https://github.com/brauceunix/4.4BSD-Lite2
C | 1043 lines | 849 code | 64 blank | 130 comment | 292 complexity | a070307742ef85a5a5df36d8b488679a MD5 | raw file
  1. /*
  2. * Copyright (c) 1982, 1986, 1988, 1990, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. * must display the following acknowledgement:
  15. * This product includes software developed by the University of
  16. * California, Berkeley and its contributors.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * @(#)uipc_socket.c 8.6 (Berkeley) 5/2/95
  34. */
  35. #include <sys/param.h>
  36. #include <sys/systm.h>
  37. #include <sys/proc.h>
  38. #include <sys/file.h>
  39. #include <sys/malloc.h>
  40. #include <sys/mbuf.h>
  41. #include <sys/domain.h>
  42. #include <sys/kernel.h>
  43. #include <sys/protosw.h>
  44. #include <sys/signalvar.h>
  45. #include <sys/socket.h>
  46. #include <sys/socketvar.h>
  47. #include <sys/resourcevar.h>
  48. int uiomove(caddr_t, int, struct uio *);
  49. /*
  50. * Socket operation routines.
  51. * These routines are called by the routines in
  52. * sys_socket.c or from a system process, and
  53. * implement the semantics of socket operations by
  54. * switching out to the protocol specific routines.
  55. */
  56. /*ARGSUSED*/
  57. int
  58. socreate(dom, aso, type, proto)
  59. int dom;
  60. struct socket **aso;
  61. register int type;
  62. int proto;
  63. {
  64. struct proc *p = curproc; /* XXX */
  65. register struct protosw *prp;
  66. register struct socket *so;
  67. register int error;
  68. if (proto)
  69. prp = pffindproto(dom, proto, type);
  70. else
  71. prp = pffindtype(dom, type);
  72. if (prp == 0 || prp->pr_usrreq == 0)
  73. return (EPROTONOSUPPORT);
  74. if (prp->pr_type != type)
  75. return (EPROTOTYPE);
  76. MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
  77. bzero((caddr_t)so, sizeof(*so));
  78. so->so_type = type;
  79. if (p->p_ucred->cr_uid == 0)
  80. so->so_state = SS_PRIV;
  81. so->so_proto = prp;
  82. error = (*prp->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0,
  83. (struct mbuf *)(long)proto, (struct mbuf *)0);
  84. if (error) {
  85. so->so_state |= SS_NOFDREF;
  86. sofree(so);
  87. return (error);
  88. }
  89. *aso = so;
  90. return (0);
  91. }
  92. int
  93. sobind(so, nam)
  94. struct socket *so;
  95. struct mbuf *nam;
  96. {
  97. int s = splnet();
  98. int error;
  99. error =
  100. (*so->so_proto->pr_usrreq)(so, PRU_BIND,
  101. (struct mbuf *)0, nam, (struct mbuf *)0);
  102. splx(s);
  103. return (error);
  104. }
  105. int
  106. solisten(so, backlog)
  107. register struct socket *so;
  108. int backlog;
  109. {
  110. int s = splnet(), error;
  111. error =
  112. (*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
  113. (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
  114. if (error) {
  115. splx(s);
  116. return (error);
  117. }
  118. if (so->so_q == 0)
  119. so->so_options |= SO_ACCEPTCONN;
  120. if (backlog < 0)
  121. backlog = 0;
  122. so->so_qlimit = min(backlog, SOMAXCONN);
  123. splx(s);
  124. return (0);
  125. }
  126. void
  127. sofree(so)
  128. register struct socket *so;
  129. {
  130. if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
  131. return;
  132. if (so->so_head) {
  133. if (!soqremque(so, 0) && !soqremque(so, 1))
  134. panic("sofree dq");
  135. so->so_head = 0;
  136. }
  137. sbrelease(&so->so_snd);
  138. sorflush(so);
  139. FREE(so, M_SOCKET);
  140. }
  141. /*
  142. * Close a socket on last file table reference removal.
  143. * Initiate disconnect if connected.
  144. * Free socket when disconnect complete.
  145. */
  146. int
  147. soclose(so)
  148. register struct socket *so;
  149. {
  150. int s = splnet(); /* conservative */
  151. int error = 0;
  152. if (so->so_options & SO_ACCEPTCONN) {
  153. while (so->so_q0)
  154. (void) soabort(so->so_q0);
  155. while (so->so_q)
  156. (void) soabort(so->so_q);
  157. }
  158. if (so->so_pcb == 0)
  159. goto discard;
  160. if (so->so_state & SS_ISCONNECTED) {
  161. if ((so->so_state & SS_ISDISCONNECTING) == 0) {
  162. error = sodisconnect(so);
  163. if (error)
  164. goto drop;
  165. }
  166. if (so->so_options & SO_LINGER) {
  167. if ((so->so_state & SS_ISDISCONNECTING) &&
  168. (so->so_state & SS_NBIO))
  169. goto drop;
  170. while (so->so_state & SS_ISCONNECTED)
  171. if ( (error = tsleep((caddr_t)&so->so_timeo,
  172. PSOCK | PCATCH, netcls, so->so_linger * hz)) != 0)
  173. break;
  174. }
  175. }
  176. drop:
  177. if (so->so_pcb) {
  178. int error2 =
  179. (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
  180. (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
  181. if (error == 0)
  182. error = error2;
  183. }
  184. discard:
  185. if (so->so_state & SS_NOFDREF)
  186. panic("soclose: NOFDREF");
  187. so->so_state |= SS_NOFDREF;
  188. sofree(so);
  189. splx(s);
  190. return (error);
  191. }
  192. /*
  193. * Must be called at splnet...
  194. */
  195. int
  196. soabort(so)
  197. struct socket *so;
  198. {
  199. return (
  200. (*so->so_proto->pr_usrreq)(so, PRU_ABORT,
  201. (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
  202. }
  203. int
  204. soaccept(so, nam)
  205. register struct socket *so;
  206. struct mbuf *nam;
  207. {
  208. int s = splnet();
  209. int error;
  210. if ((so->so_state & SS_NOFDREF) == 0)
  211. panic("soaccept: !NOFDREF");
  212. so->so_state &= ~SS_NOFDREF;
  213. error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
  214. (struct mbuf *)0, nam, (struct mbuf *)0);
  215. splx(s);
  216. return (error);
  217. }
  218. int
  219. soconnect(so, nam)
  220. register struct socket *so;
  221. struct mbuf *nam;
  222. {
  223. int s;
  224. int error;
  225. if (so->so_options & SO_ACCEPTCONN)
  226. return (EOPNOTSUPP);
  227. s = splnet();
  228. /*
  229. * If protocol is connection-based, can only connect once.
  230. * Otherwise, if connected, try to disconnect first.
  231. * This allows user to disconnect by connecting to, e.g.,
  232. * a null address.
  233. */
  234. if (so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING) &&
  235. ((so->so_proto->pr_flags & PR_CONNREQUIRED) ||
  236. (error = sodisconnect(so))))
  237. error = EISCONN;
  238. else
  239. error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
  240. (struct mbuf *)0, nam, (struct mbuf *)0);
  241. splx(s);
  242. return (error);
  243. }
  244. int
  245. soconnect2(so1, so2)
  246. register struct socket *so1;
  247. struct socket *so2;
  248. {
  249. int s = splnet();
  250. int error;
  251. error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
  252. (struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
  253. splx(s);
  254. return (error);
  255. }
  256. int
  257. sodisconnect(so)
  258. register struct socket *so;
  259. {
  260. int s = splnet();
  261. int error;
  262. if ((so->so_state & SS_ISCONNECTED) == 0) {
  263. error = ENOTCONN;
  264. goto bad;
  265. }
  266. if (so->so_state & SS_ISDISCONNECTING) {
  267. error = EALREADY;
  268. goto bad;
  269. }
  270. error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
  271. (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
  272. bad:
  273. splx(s);
  274. return (error);
  275. }
  276. #define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
  277. /*
  278. * Send on a socket.
  279. * If send must go all at once and message is larger than
  280. * send buffering, then hard error.
  281. * Lock against other senders.
  282. * If must go all at once and not enough room now, then
  283. * inform user that this would block and do nothing.
  284. * Otherwise, if nonblocking, send as much as possible.
  285. * The data to be sent is described by "uio" if nonzero,
  286. * otherwise by the mbuf chain "top" (which must be null
  287. * if uio is not). Data provided in mbuf chain must be small
  288. * enough to send all at once.
  289. *
  290. * Returns nonzero on error, timeout or signal; callers
  291. * must check for short counts if EINTR/ERESTART are returned.
  292. * Data and control buffers are freed on return.
  293. */
  294. int
  295. sosend(so, addr, uio, top, control, flags)
  296. register struct socket *so;
  297. struct mbuf *addr;
  298. struct uio *uio;
  299. struct mbuf *top;
  300. struct mbuf *control;
  301. int flags;
  302. {
  303. struct proc *p = curproc; /* XXX */
  304. struct mbuf **mp;
  305. register struct mbuf *m;
  306. register long space, len, resid;
  307. int clen = 0, error, s, dontroute, mlen;
  308. int atomic = sosendallatonce(so) || top;
  309. if (uio)
  310. resid = uio->uio_resid;
  311. else
  312. resid = top->m_pkthdr.len;
  313. /*
  314. * In theory resid should be unsigned.
  315. * However, space must be signed, as it might be less than 0
  316. * if we over-committed, and we must use a signed comparison
  317. * of space and resid. On the other hand, a negative resid
  318. * causes us to loop sending 0-length segments to the protocol.
  319. */
  320. if (resid < 0)
  321. return (EINVAL);
  322. dontroute =
  323. (flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
  324. (so->so_proto->pr_flags & PR_ATOMIC);
  325. p->p_stats->p_ru.ru_msgsnd++;
  326. if (control)
  327. clen = control->m_len;
  328. #define snderr(errno) { error = errno; splx(s); goto release; }
  329. restart:
  330. if ( (error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
  331. goto out;
  332. do {
  333. s = splnet();
  334. if (so->so_state & SS_CANTSENDMORE)
  335. snderr(EPIPE);
  336. if (so->so_error)
  337. snderr(so->so_error);
  338. if ((so->so_state & SS_ISCONNECTED) == 0) {
  339. if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
  340. if ((so->so_state & SS_ISCONFIRMING) == 0 &&
  341. !(resid == 0 && clen != 0))
  342. snderr(ENOTCONN);
  343. } else if (addr == 0)
  344. snderr(EDESTADDRREQ);
  345. }
  346. space = sbspace(&so->so_snd);
  347. if (flags & MSG_OOB)
  348. space += 1024;
  349. if ((atomic && resid > so->so_snd.sb_hiwat) ||
  350. clen > so->so_snd.sb_hiwat)
  351. snderr(EMSGSIZE);
  352. if (space < resid + clen && uio &&
  353. (atomic || space < so->so_snd.sb_lowat || space < clen)) {
  354. if (so->so_state & SS_NBIO)
  355. snderr(EWOULDBLOCK);
  356. sbunlock(&so->so_snd);
  357. error = sbwait(&so->so_snd);
  358. splx(s);
  359. if (error)
  360. goto out;
  361. goto restart;
  362. }
  363. splx(s);
  364. mp = &top;
  365. space -= clen;
  366. do {
  367. if (uio == NULL) {
  368. /*
  369. * Data is prepackaged in "top".
  370. */
  371. resid = 0;
  372. if (flags & MSG_EOR)
  373. top->m_flags |= M_EOR;
  374. } else do {
  375. if (top == 0) {
  376. MGETHDR(m, M_WAIT, MT_DATA);
  377. mlen = MHLEN;
  378. m->m_pkthdr.len = 0;
  379. m->m_pkthdr.rcvif = (struct ifnet *)0;
  380. } else {
  381. MGET(m, M_WAIT, MT_DATA);
  382. mlen = MLEN;
  383. }
  384. if (resid >= MINCLSIZE && space >= MCLBYTES) {
  385. MCLGET(m, M_WAIT);
  386. if ((m->m_flags & M_EXT) == 0)
  387. goto nopages;
  388. mlen = MCLBYTES;
  389. #ifdef MAPPED_MBUFS
  390. len = min(MCLBYTES, resid);
  391. #else
  392. if (atomic && top == 0) {
  393. len = min(MCLBYTES - max_hdr, resid);
  394. m->m_data += max_hdr;
  395. } else
  396. len = min(MCLBYTES, resid);
  397. #endif
  398. space -= MCLBYTES;
  399. } else {
  400. nopages:
  401. len = min(min(mlen, resid), space);
  402. space -= len;
  403. /*
  404. * For datagram protocols, leave room
  405. * for protocol headers in first mbuf.
  406. */
  407. if (atomic && top == 0 && len < mlen)
  408. MH_ALIGN(m, len);
  409. }
  410. error = uiomove(mtod(m, caddr_t), (int)len, uio);
  411. resid = uio->uio_resid;
  412. m->m_len = len;
  413. *mp = m;
  414. top->m_pkthdr.len += len;
  415. if (error)
  416. goto release;
  417. mp = &m->m_next;
  418. if (resid <= 0) {
  419. if (flags & MSG_EOR)
  420. top->m_flags |= M_EOR;
  421. break;
  422. }
  423. } while (space > 0 && atomic);
  424. if (dontroute)
  425. so->so_options |= SO_DONTROUTE;
  426. s = splnet(); /* XXX */
  427. error = (*so->so_proto->pr_usrreq)(so,
  428. (flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
  429. top, addr, control);
  430. splx(s);
  431. if (dontroute)
  432. so->so_options &= ~SO_DONTROUTE;
  433. clen = 0;
  434. control = 0;
  435. top = 0;
  436. mp = &top;
  437. if (error)
  438. goto release;
  439. } while (resid && space > 0);
  440. } while (resid);
  441. release:
  442. sbunlock(&so->so_snd);
  443. out:
  444. if (top)
  445. m_freem(top);
  446. if (control)
  447. m_freem(control);
  448. return (error);
  449. }
  450. /*
  451. * Implement receive operations on a socket.
  452. * We depend on the way that records are added to the sockbuf
  453. * by sbappend*. In particular, each record (mbufs linked through m_next)
  454. * must begin with an address if the protocol so specifies,
  455. * followed by an optional mbuf or mbufs containing ancillary data,
  456. * and then zero or more mbufs of data.
  457. * In order to avoid blocking network interrupts for the entire time here,
  458. * we splx() while doing the actual copy to user space.
  459. * Although the sockbuf is locked, new data may still be appended,
  460. * and thus we must maintain consistency of the sockbuf during that time.
  461. *
  462. * The caller may receive the data as a single mbuf chain by supplying
  463. * an mbuf **mp0 for use in returning the chain. The uio is then used
  464. * only for the count in uio_resid.
  465. */
  466. int
  467. soreceive(so, paddr, uio, mp0, controlp, flagsp)
  468. register struct socket *so;
  469. struct mbuf **paddr;
  470. struct uio *uio;
  471. struct mbuf **mp0;
  472. struct mbuf **controlp;
  473. int *flagsp;
  474. {
  475. register struct mbuf *m, **mp;
  476. register int flags, len, error, s, offset;
  477. struct protosw *pr = so->so_proto;
  478. struct mbuf *nextrecord;
  479. int moff, type;
  480. int orig_resid = uio->uio_resid;
  481. mp = mp0;
  482. if (paddr)
  483. *paddr = 0;
  484. if (controlp)
  485. *controlp = 0;
  486. if (flagsp)
  487. flags = *flagsp &~ MSG_EOR;
  488. else
  489. flags = 0;
  490. if (flags & MSG_OOB) {
  491. m = m_get(M_WAIT, MT_DATA);
  492. error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
  493. (struct mbuf *)(long)(flags & MSG_PEEK), (struct mbuf *)0);
  494. if (error)
  495. goto bad;
  496. do {
  497. error = uiomove(mtod(m, caddr_t),
  498. (int) min(uio->uio_resid, m->m_len), uio);
  499. m = m_free(m);
  500. } while (uio->uio_resid && error == 0 && m);
  501. bad:
  502. if (m)
  503. m_freem(m);
  504. return (error);
  505. }
  506. if (mp)
  507. *mp = (struct mbuf *)0;
  508. if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
  509. (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
  510. (struct mbuf *)0, (struct mbuf *)0);
  511. restart:
  512. if ( (error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
  513. return (error);
  514. s = splnet();
  515. m = so->so_rcv.sb_mb;
  516. /*
  517. * If we have less data than requested, block awaiting more
  518. * (subject to any timeout) if:
  519. * 1. the current count is less than the low water mark, or
  520. * 2. MSG_WAITALL is set, and it is possible to do the entire
  521. * receive operation at once if we block (resid <= hiwat), or
  522. * 3. MSG_DONTWAIT is not set.
  523. * If MSG_WAITALL is set but resid is larger than the receive buffer,
  524. * we have to do the receive in sections, and thus risk returning
  525. * a short count if a timeout or signal occurs after we start.
  526. */
  527. if (m == 0 || ((flags & MSG_DONTWAIT) == 0 &&
  528. so->so_rcv.sb_cc < uio->uio_resid) &&
  529. (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
  530. ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
  531. m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0) {
  532. #ifdef DIAGNOSTIC
  533. if (m == 0 && so->so_rcv.sb_cc)
  534. panic("receive 1");
  535. #endif
  536. if (so->so_error) {
  537. if (m)
  538. goto dontblock;
  539. error = so->so_error;
  540. if ((flags & MSG_PEEK) == 0)
  541. so->so_error = 0;
  542. goto release;
  543. }
  544. if (so->so_state & SS_CANTRCVMORE) {
  545. if (m)
  546. goto dontblock;
  547. else
  548. goto release;
  549. }
  550. for (; m; m = m->m_next)
  551. if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) {
  552. m = so->so_rcv.sb_mb;
  553. goto dontblock;
  554. }
  555. if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
  556. (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
  557. error = ENOTCONN;
  558. goto release;
  559. }
  560. if (uio->uio_resid == 0)
  561. goto release;
  562. if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
  563. error = EWOULDBLOCK;
  564. goto release;
  565. }
  566. sbunlock(&so->so_rcv);
  567. error = sbwait(&so->so_rcv);
  568. splx(s);
  569. if (error)
  570. return (error);
  571. goto restart;
  572. }
  573. dontblock:
  574. if (uio->uio_procp)
  575. uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
  576. nextrecord = m->m_nextpkt;
  577. if (pr->pr_flags & PR_ADDR) {
  578. #ifdef DIAGNOSTIC
  579. if (m->m_type != MT_SONAME)
  580. panic("receive 1a");
  581. #endif
  582. orig_resid = 0;
  583. if (flags & MSG_PEEK) {
  584. if (paddr)
  585. *paddr = m_copy(m, 0, m->m_len);
  586. m = m->m_next;
  587. } else {
  588. sbfree(&so->so_rcv, m);
  589. if (paddr) {
  590. *paddr = m;
  591. so->so_rcv.sb_mb = m->m_next;
  592. m->m_next = 0;
  593. m = so->so_rcv.sb_mb;
  594. } else {
  595. MFREE(m, so->so_rcv.sb_mb);
  596. m = so->so_rcv.sb_mb;
  597. }
  598. }
  599. }
  600. while (m && m->m_type == MT_CONTROL && error == 0) {
  601. if (flags & MSG_PEEK) {
  602. if (controlp)
  603. *controlp = m_copy(m, 0, m->m_len);
  604. m = m->m_next;
  605. } else {
  606. sbfree(&so->so_rcv, m);
  607. if (controlp) {
  608. if (pr->pr_domain->dom_externalize &&
  609. mtod(m, struct cmsghdr *)->cmsg_type ==
  610. SCM_RIGHTS)
  611. error = (*pr->pr_domain->dom_externalize)(m);
  612. *controlp = m;
  613. so->so_rcv.sb_mb = m->m_next;
  614. m->m_next = 0;
  615. m = so->so_rcv.sb_mb;
  616. } else {
  617. MFREE(m, so->so_rcv.sb_mb);
  618. m = so->so_rcv.sb_mb;
  619. }
  620. }
  621. if (controlp) {
  622. orig_resid = 0;
  623. controlp = &(*controlp)->m_next;
  624. }
  625. }
  626. if (m) {
  627. if ((flags & MSG_PEEK) == 0)
  628. m->m_nextpkt = nextrecord;
  629. type = m->m_type;
  630. if (type == MT_OOBDATA)
  631. flags |= MSG_OOB;
  632. }
  633. moff = 0;
  634. offset = 0;
  635. while (m && uio->uio_resid > 0 && error == 0) {
  636. if (m->m_type == MT_OOBDATA) {
  637. if (type != MT_OOBDATA)
  638. break;
  639. } else if (type == MT_OOBDATA)
  640. break;
  641. #ifdef DIAGNOSTIC
  642. else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
  643. panic("receive 3");
  644. #endif
  645. so->so_state &= ~SS_RCVATMARK;
  646. len = uio->uio_resid;
  647. if (so->so_oobmark && len > so->so_oobmark - offset)
  648. len = so->so_oobmark - offset;
  649. if (len > m->m_len - moff)
  650. len = m->m_len - moff;
  651. /*
  652. * If mp is set, just pass back the mbufs.
  653. * Otherwise copy them out via the uio, then free.
  654. * Sockbuf must be consistent here (points to current mbuf,
  655. * it points to next record) when we drop priority;
  656. * we must note any additions to the sockbuf when we
  657. * block interrupts again.
  658. */
  659. if (mp == 0) {
  660. splx(s);
  661. error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
  662. s = splnet();
  663. } else
  664. uio->uio_resid -= len;
  665. if (len == m->m_len - moff) {
  666. if (m->m_flags & M_EOR)
  667. flags |= MSG_EOR;
  668. if (flags & MSG_PEEK) {
  669. m = m->m_next;
  670. moff = 0;
  671. } else {
  672. nextrecord = m->m_nextpkt;
  673. sbfree(&so->so_rcv, m);
  674. if (mp) {
  675. *mp = m;
  676. mp = &m->m_next;
  677. so->so_rcv.sb_mb = m = m->m_next;
  678. *mp = (struct mbuf *)0;
  679. } else {
  680. MFREE(m, so->so_rcv.sb_mb);
  681. m = so->so_rcv.sb_mb;
  682. }
  683. if (m)
  684. m->m_nextpkt = nextrecord;
  685. }
  686. } else {
  687. if (flags & MSG_PEEK)
  688. moff += len;
  689. else {
  690. if (mp)
  691. *mp = m_copym(m, 0, len, M_WAIT);
  692. m->m_data += len;
  693. m->m_len -= len;
  694. so->so_rcv.sb_cc -= len;
  695. }
  696. }
  697. if (so->so_oobmark) {
  698. if ((flags & MSG_PEEK) == 0) {
  699. so->so_oobmark -= len;
  700. if (so->so_oobmark == 0) {
  701. so->so_state |= SS_RCVATMARK;
  702. break;
  703. }
  704. } else {
  705. offset += len;
  706. if (offset == so->so_oobmark)
  707. break;
  708. }
  709. }
  710. if (flags & MSG_EOR)
  711. break;
  712. /*
  713. * If the MSG_WAITALL flag is set (for non-atomic socket),
  714. * we must not quit until "uio->uio_resid == 0" or an error
  715. * termination. If a signal/timeout occurs, return
  716. * with a short count but without error.
  717. * Keep sockbuf locked against other readers.
  718. */
  719. while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
  720. !sosendallatonce(so) && !nextrecord) {
  721. if (so->so_error || so->so_state & SS_CANTRCVMORE)
  722. break;
  723. error = sbwait(&so->so_rcv);
  724. if (error) {
  725. sbunlock(&so->so_rcv);
  726. splx(s);
  727. return (0);
  728. }
  729. if ( (m = so->so_rcv.sb_mb) != NULL)
  730. nextrecord = m->m_nextpkt;
  731. }
  732. }
  733. if (m && pr->pr_flags & PR_ATOMIC) {
  734. flags |= MSG_TRUNC;
  735. if ((flags & MSG_PEEK) == 0)
  736. (void) sbdroprecord(&so->so_rcv);
  737. }
  738. if ((flags & MSG_PEEK) == 0) {
  739. if (m == 0)
  740. so->so_rcv.sb_mb = nextrecord;
  741. if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
  742. (*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
  743. (struct mbuf *)(long)flags, (struct mbuf *)0,
  744. (struct mbuf *)0);
  745. }
  746. if (orig_resid == uio->uio_resid && orig_resid &&
  747. (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
  748. sbunlock(&so->so_rcv);
  749. splx(s);
  750. goto restart;
  751. }
  752. if (flagsp)
  753. *flagsp |= flags;
  754. release:
  755. sbunlock(&so->so_rcv);
  756. splx(s);
  757. return (error);
  758. }
  759. int
  760. soshutdown(so, how)
  761. register struct socket *so;
  762. register int how;
  763. {
  764. register struct protosw *pr = so->so_proto;
  765. how++;
  766. if (how & FREAD)
  767. sorflush(so);
  768. if (how & FWRITE)
  769. return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,
  770. (struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
  771. return (0);
  772. }
  773. void
  774. sorflush(so)
  775. register struct socket *so;
  776. {
  777. register struct sockbuf *sb = &so->so_rcv;
  778. register struct protosw *pr = so->so_proto;
  779. register int s;
  780. struct sockbuf asb;
  781. sb->sb_flags |= SB_NOINTR;
  782. (void) sblock(sb, M_WAITOK);
  783. s = splimp();
  784. socantrcvmore(so);
  785. sbunlock(sb);
  786. asb = *sb;
  787. bzero((caddr_t)sb, sizeof (*sb));
  788. splx(s);
  789. if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
  790. (*pr->pr_domain->dom_dispose)(asb.sb_mb);
  791. sbrelease(&asb);
  792. }
  793. int
  794. sosetopt(so, level, optname, m0)
  795. register struct socket *so;
  796. int level, optname;
  797. struct mbuf *m0;
  798. {
  799. int error = 0;
  800. register struct mbuf *m = m0;
  801. if (level != SOL_SOCKET) {
  802. if (so->so_proto && so->so_proto->pr_ctloutput)
  803. return ((*so->so_proto->pr_ctloutput)
  804. (PRCO_SETOPT, so, level, optname, &m0));
  805. error = ENOPROTOOPT;
  806. } else {
  807. switch (optname) {
  808. case SO_LINGER:
  809. if (m == NULL || m->m_len != sizeof (struct linger)) {
  810. error = EINVAL;
  811. goto bad;
  812. }
  813. so->so_linger = mtod(m, struct linger *)->l_linger;
  814. /* fall thru... */
  815. case SO_DEBUG:
  816. case SO_KEEPALIVE:
  817. case SO_DONTROUTE:
  818. case SO_USELOOPBACK:
  819. case SO_BROADCAST:
  820. case SO_REUSEADDR:
  821. case SO_REUSEPORT:
  822. case SO_OOBINLINE:
  823. if (m == NULL || m->m_len < sizeof (int)) {
  824. error = EINVAL;
  825. goto bad;
  826. }
  827. if (*mtod(m, int *))
  828. so->so_options |= optname;
  829. else
  830. so->so_options &= ~optname;
  831. break;
  832. case SO_SNDBUF:
  833. case SO_RCVBUF:
  834. case SO_SNDLOWAT:
  835. case SO_RCVLOWAT:
  836. if (m == NULL || m->m_len < sizeof (int)) {
  837. error = EINVAL;
  838. goto bad;
  839. }
  840. switch (optname) {
  841. case SO_SNDBUF:
  842. case SO_RCVBUF:
  843. if (sbreserve(optname == SO_SNDBUF ?
  844. &so->so_snd : &so->so_rcv,
  845. (u_long) *mtod(m, int *)) == 0) {
  846. error = ENOBUFS;
  847. goto bad;
  848. }
  849. break;
  850. case SO_SNDLOWAT:
  851. so->so_snd.sb_lowat = *mtod(m, int *);
  852. break;
  853. case SO_RCVLOWAT:
  854. so->so_rcv.sb_lowat = *mtod(m, int *);
  855. break;
  856. }
  857. break;
  858. case SO_SNDTIMEO:
  859. case SO_RCVTIMEO:
  860. {
  861. struct timeval *tv;
  862. short val;
  863. if (m == NULL || m->m_len < sizeof (*tv)) {
  864. error = EINVAL;
  865. goto bad;
  866. }
  867. tv = mtod(m, struct timeval *);
  868. if (tv->tv_sec * hz + tv->tv_usec / tick > SHRT_MAX) {
  869. error = EDOM;
  870. goto bad;
  871. }
  872. val = tv->tv_sec * hz + tv->tv_usec / tick;
  873. switch (optname) {
  874. case SO_SNDTIMEO:
  875. so->so_snd.sb_timeo = val;
  876. break;
  877. case SO_RCVTIMEO:
  878. so->so_rcv.sb_timeo = val;
  879. break;
  880. }
  881. break;
  882. }
  883. default:
  884. error = ENOPROTOOPT;
  885. break;
  886. }
  887. if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
  888. (void) ((*so->so_proto->pr_ctloutput)
  889. (PRCO_SETOPT, so, level, optname, &m0));
  890. m = NULL; /* freed by protocol */
  891. }
  892. }
  893. bad:
  894. if (m)
  895. (void) m_free(m);
  896. return (error);
  897. }
  898. int
  899. sogetopt(so, level, optname, mp)
  900. register struct socket *so;
  901. int level, optname;
  902. struct mbuf **mp;
  903. {
  904. register struct mbuf *m;
  905. if (level != SOL_SOCKET) {
  906. if (so->so_proto && so->so_proto->pr_ctloutput) {
  907. return ((*so->so_proto->pr_ctloutput)
  908. (PRCO_GETOPT, so, level, optname, mp));
  909. } else
  910. return (ENOPROTOOPT);
  911. } else {
  912. m = m_get(M_WAIT, MT_SOOPTS);
  913. m->m_len = sizeof (int);
  914. switch (optname) {
  915. case SO_LINGER:
  916. m->m_len = sizeof (struct linger);
  917. mtod(m, struct linger *)->l_onoff =
  918. so->so_options & SO_LINGER;
  919. mtod(m, struct linger *)->l_linger = so->so_linger;
  920. break;
  921. case SO_USELOOPBACK:
  922. case SO_DONTROUTE:
  923. case SO_DEBUG:
  924. case SO_KEEPALIVE:
  925. case SO_REUSEADDR:
  926. case SO_REUSEPORT:
  927. case SO_BROADCAST:
  928. case SO_OOBINLINE:
  929. *mtod(m, int *) = so->so_options & optname;
  930. break;
  931. case SO_TYPE:
  932. *mtod(m, int *) = so->so_type;
  933. break;
  934. case SO_ERROR:
  935. *mtod(m, int *) = so->so_error;
  936. so->so_error = 0;
  937. break;
  938. case SO_SNDBUF:
  939. *mtod(m, int *) = so->so_snd.sb_hiwat;
  940. break;
  941. case SO_RCVBUF:
  942. *mtod(m, int *) = so->so_rcv.sb_hiwat;
  943. break;
  944. case SO_SNDLOWAT:
  945. *mtod(m, int *) = so->so_snd.sb_lowat;
  946. break;
  947. case SO_RCVLOWAT:
  948. *mtod(m, int *) = so->so_rcv.sb_lowat;
  949. break;
  950. case SO_SNDTIMEO:
  951. case SO_RCVTIMEO:
  952. {
  953. int val = (optname == SO_SNDTIMEO ?
  954. so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
  955. m->m_len = sizeof(struct timeval);
  956. mtod(m, struct timeval *)->tv_sec = val / hz;
  957. mtod(m, struct timeval *)->tv_usec =
  958. (val % hz) * tick;
  959. break;
  960. }
  961. default:
  962. (void)m_free(m);
  963. return (ENOPROTOOPT);
  964. }
  965. *mp = m;
  966. return (0);
  967. }
  968. }
  969. void
  970. sohasoutofband(so)
  971. register struct socket *so;
  972. {
  973. struct proc *p;
  974. if (so->so_pgid < 0)
  975. gsignal(-so->so_pgid, SIGURG);
  976. else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
  977. psignal(p, SIGURG);
  978. selwakeup(&so->so_rcv.sb_sel);
  979. }