PageRenderTime 76ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/kern/uipc_socket.c

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