PageRenderTime 66ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/bsd/sys/kern/uipc_syscalls.cc

https://gitlab.com/jforge/osv
C++ | 1104 lines | 894 code | 125 blank | 85 comment | 197 complexity | 5e3b5d327d1cd3d7b808a0b59d5a0d0a MD5 | raw file
Possible License(s): BSD-3-Clause, 0BSD, MPL-2.0-no-copyleft-exception
  1. /*-
  2. * Copyright (c) 1982, 1986, 1989, 1990, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * sendfile(2) and related extensions:
  6. * Copyright (c) 1998, David Greenman. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 4. Neither the name of the University nor the names of its contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
  33. */
  34. #include <sys/cdefs.h>
  35. #include <bsd/porting/netport.h>
  36. #include <bsd/uipc_syscalls.h>
  37. #include <fcntl.h>
  38. #include <osv/fcntl.h>
  39. #include <osv/ioctl.h>
  40. #include <errno.h>
  41. #include <bsd/sys/sys/param.h>
  42. #include <bsd/porting/synch.h>
  43. #include <osv/file.h>
  44. #include <osv/socket.hh>
  45. #include <bsd/sys/sys/mbuf.h>
  46. #include <bsd/sys/sys/protosw.h>
  47. #include <bsd/sys/sys/socket.h>
  48. #include <bsd/sys/sys/socketvar.h>
  49. #include <osv/uio.h>
  50. #include <bsd/sys/net/vnet.h>
  51. #include <memory>
  52. #include <fs/fs.hh>
  53. #include <osv/defer.hh>
  54. #include <osv/mempool.hh>
  55. #include <osv/pagealloc.hh>
  56. #include <osv/zcopy.hh>
  57. #include <sys/eventfd.h>
  58. using namespace std;
  59. /* FIXME: OSv - implement... */
  60. #if 0
  61. static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat);
  62. static int getsockname1(struct thread *td, struct getsockname_args *uap,
  63. int compat);
  64. #endif
  65. /*
  66. * NSFBUFS-related variables and associated sysctls
  67. */
  68. int nsfbufs;
  69. int nsfbufspeak;
  70. int nsfbufsused;
  71. SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufs, CTLFLAG_RDTUN, &nsfbufs, 0,
  72. "Maximum number of sendfile(2) sf_bufs available");
  73. SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufspeak, CTLFLAG_RD, &nsfbufspeak, 0,
  74. "Number of sendfile(2) sf_bufs at peak usage");
  75. SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
  76. "Number of sendfile(2) sf_bufs in use");
  77. /*
  78. * Convert a user file descriptor to a kernel file entry.
  79. * A reference on the file entry is held upon returning.
  80. */
  81. static int
  82. getsock_cap(int fd, struct file **fpp, u_int *fflagp)
  83. {
  84. struct file *fp;
  85. int error;
  86. fp = NULL;
  87. error = fget(fd, &fp);
  88. if (error)
  89. return (error);
  90. if (file_type(fp) != DTYPE_SOCKET) {
  91. fdrop(fp);
  92. return (ENOTSOCK);
  93. }
  94. if (fflagp != NULL)
  95. *fflagp = file_flags(fp);
  96. *fpp = fp;
  97. return (0);
  98. }
  99. socketref socreate(int dom, int type, int proto)
  100. {
  101. socket* so;
  102. int error = socreate(dom, &so, type, proto, nullptr, nullptr);
  103. if (error) {
  104. throw error;
  105. }
  106. return socketref(so);
  107. }
  108. /*
  109. * System call interface to the socket abstraction.
  110. */
  111. int
  112. sys_socket(int domain, int type, int protocol, int *out_fd)
  113. {
  114. try {
  115. auto so = socreate(domain, type, protocol);
  116. fileref fp = make_file<socket_file>(FREAD | FWRITE, move(so));
  117. fdesc fd(fp);
  118. *out_fd = fd.release();
  119. return 0;
  120. } catch (int error) {
  121. return error;
  122. }
  123. }
  124. /* ARGSUSED */
  125. int
  126. sys_bind(int s, struct bsd_sockaddr *sa, int namelen)
  127. {
  128. int error;
  129. sa->sa_len = namelen;
  130. error = kern_bind(s, sa);
  131. return (error);
  132. }
  133. int
  134. kern_bind(int fd, struct bsd_sockaddr *sa)
  135. {
  136. struct socket *so;
  137. struct file *fp;
  138. int error;
  139. error = getsock_cap(fd, &fp, NULL);
  140. if (error)
  141. return (error);
  142. so = (socket*)file_data(fp);
  143. error = sobind(so, sa, 0);
  144. fdrop(fp);
  145. return (error);
  146. }
  147. /* ARGSUSED */
  148. int
  149. sys_listen(int s, int backlog)
  150. {
  151. struct socket *so;
  152. struct file *fp;
  153. int error;
  154. error = getsock_cap(s, &fp, NULL);
  155. if (error) {
  156. return error;
  157. }
  158. so = (socket*)file_data(fp);
  159. error = solisten(so, backlog, 0);
  160. fdrop(fp);
  161. return(error);
  162. }
  163. /*
  164. * accept1()
  165. */
  166. static int
  167. accept1(int s,
  168. struct bsd_sockaddr * name,
  169. socklen_t * namelen, int *out_fd)
  170. {
  171. int error;
  172. if (name == NULL)
  173. return (kern_accept(s, NULL, NULL, NULL, out_fd));
  174. error = kern_accept(s, name, namelen, NULL, out_fd);
  175. return (error);
  176. }
  177. int
  178. kern_accept(int s, struct bsd_sockaddr *name,
  179. socklen_t *namelen, struct file **out_fp, int *out_fd)
  180. {
  181. struct file *headfp, *nfp = NULL;
  182. struct bsd_sockaddr *sa = NULL;
  183. int error;
  184. struct socket *head, *so;
  185. int fd;
  186. u_int fflag;
  187. int tmp;
  188. if ((name) && (*namelen < 0)) {
  189. return (EINVAL);
  190. }
  191. error = getsock_cap(s, &headfp, &fflag);
  192. if (error)
  193. return (error);
  194. head = (socket*)file_data(headfp);
  195. if ((head->so_options & SO_ACCEPTCONN) == 0) {
  196. error = EINVAL;
  197. goto done;
  198. }
  199. ACCEPT_LOCK();
  200. if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
  201. ACCEPT_UNLOCK();
  202. error = EWOULDBLOCK;
  203. goto noconnection;
  204. }
  205. while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
  206. if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
  207. head->so_error = ECONNABORTED;
  208. break;
  209. }
  210. error = msleep(&head->so_timeo, &accept_mtx, 0, "accept", 0);
  211. if (error) {
  212. ACCEPT_UNLOCK();
  213. goto noconnection;
  214. }
  215. }
  216. if (head->so_error) {
  217. error = head->so_error;
  218. head->so_error = 0;
  219. ACCEPT_UNLOCK();
  220. goto noconnection;
  221. }
  222. so = TAILQ_FIRST(&head->so_comp);
  223. KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
  224. KASSERT(so->so_qstate & SQ_COMP, ("accept1: so not SQ_COMP"));
  225. /*
  226. * Before changing the flags on the socket, we have to bump the
  227. * reference count. Otherwise, if the protocol calls sofree(),
  228. * the socket will be released due to a zero refcount.
  229. */
  230. SOCK_LOCK(so); /* soref() and so_state update */
  231. soref(so); /* file descriptor reference */
  232. TAILQ_REMOVE(&head->so_comp, so, so_list);
  233. head->so_qlen--;
  234. so->so_state |= (head->so_state & SS_NBIO);
  235. so->so_qstate &= ~SQ_COMP;
  236. so->so_head = NULL;
  237. SOCK_UNLOCK(so);
  238. ACCEPT_UNLOCK();
  239. /* FIXME: OSv - Implement... select/poll */
  240. #if 0
  241. /* connection has been removed from the listen queue */
  242. KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
  243. pgid = fgetown(&head->so_sigio);
  244. if (pgid != 0)
  245. fsetown(pgid, &so->so_sigio);
  246. #endif
  247. try {
  248. auto nf = make_file<socket_file>(fflag, so);
  249. nfp = nf.get(); // want nf.release()
  250. fhold(nfp);
  251. } catch (int err) {
  252. error = err;
  253. goto noconnection;
  254. }
  255. /* Sync socket nonblocking/async state with file flags */
  256. tmp = fflag & FNONBLOCK;
  257. (void) nfp->ioctl(FIONBIO, &tmp);
  258. tmp = fflag & FASYNC;
  259. (void) nfp->ioctl(FIOASYNC, &tmp);
  260. sa = 0;
  261. error = soaccept(so, &sa);
  262. if (error)
  263. goto noconnection;
  264. if (sa == NULL)
  265. goto done;
  266. if (name) {
  267. /* check sa_len before it is destroyed */
  268. if (*namelen > sa->sa_len)
  269. *namelen = sa->sa_len;
  270. bcopy(sa, name, *namelen);
  271. }
  272. error = fdalloc(nfp, &fd);
  273. if (error)
  274. goto noconnection;
  275. /* An extra reference on `nfp' has been held for us by fdalloc(). */
  276. *out_fd = fd;
  277. noconnection:
  278. if (sa)
  279. free(sa);
  280. /*
  281. * Release explicitly held references before returning. We return
  282. * a reference on nfp to the caller on success if they request it.
  283. */
  284. done:
  285. if (out_fp != NULL) {
  286. if (error == 0) {
  287. *out_fp = nfp;
  288. nfp = NULL;
  289. } else
  290. *out_fp = NULL;
  291. }
  292. if (nfp != NULL)
  293. fdrop(nfp);
  294. fdrop(headfp);
  295. return (error);
  296. }
  297. int
  298. sys_accept(int s,
  299. struct bsd_sockaddr * name,
  300. socklen_t * namelen, int *out_fd)
  301. {
  302. return (accept1(s, name, namelen, out_fd));
  303. }
  304. /* ARGSUSED */
  305. int
  306. sys_connect(int s, struct bsd_sockaddr *sa, socklen_t len)
  307. {
  308. int error;
  309. sa->sa_len = len;
  310. error = kern_connect(s, sa);
  311. return (error);
  312. }
  313. int
  314. kern_connect(int fd, struct bsd_sockaddr *sa)
  315. {
  316. struct socket *so;
  317. struct file *fp;
  318. int error;
  319. int interrupted = 0;
  320. error = getsock_cap(fd, &fp, NULL);
  321. if (error)
  322. return (error);
  323. so = (socket*)file_data(fp);
  324. if (so->so_state & SS_ISCONNECTING) {
  325. error = EALREADY;
  326. goto done1;
  327. }
  328. error = soconnect(so, sa, 0);
  329. if (error)
  330. goto bad;
  331. if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
  332. error = EINPROGRESS;
  333. goto done1;
  334. }
  335. SOCK_LOCK(so);
  336. while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
  337. error = msleep(&so->so_timeo, SOCK_MTX(so), 0,
  338. "connec", 0);
  339. if (error) {
  340. if (error == EINTR || error == ERESTART)
  341. interrupted = 1;
  342. break;
  343. }
  344. }
  345. if (error == 0) {
  346. error = so->so_error;
  347. so->so_error = 0;
  348. }
  349. SOCK_UNLOCK(so);
  350. bad:
  351. if (!interrupted)
  352. so->so_state &= ~SS_ISCONNECTING;
  353. if (error == ERESTART)
  354. error = EINTR;
  355. done1:
  356. fdrop(fp);
  357. return (error);
  358. }
  359. int
  360. kern_socketpair(int domain, int type, int protocol, int *rsv)
  361. {
  362. try {
  363. socketref so1 = socreate(domain, type, protocol);
  364. socketref so2 = socreate(domain, type, protocol);
  365. int error = soconnect2(so1.get(), so2.get());
  366. if (error)
  367. return error;
  368. if (type == SOCK_DGRAM) {
  369. /*
  370. * Datagram socket connection is asymmetric.
  371. */
  372. error = soconnect2(so2.get(), so1.get());
  373. if (error)
  374. return error;
  375. }
  376. fileref fp1 = make_file<socket_file>(FREAD | FWRITE, move(so1));
  377. fileref fp2 = make_file<socket_file>(FREAD | FWRITE, move(so2));
  378. fdesc fd1(fp1);
  379. fdesc fd2(fp2);
  380. // end of exception territory; relax
  381. rsv[0] = fd1.release();
  382. rsv[1] = fd2.release();
  383. return 0;
  384. } catch (int error) {
  385. return error;
  386. }
  387. }
  388. int
  389. sys_socketpair(int domain, int type, int protocol, int *rsv)
  390. {
  391. return (kern_socketpair(domain, type, protocol, rsv));
  392. }
  393. static int
  394. sendit(int s, struct msghdr* mp, int flags, ssize_t* bytes)
  395. {
  396. struct mbuf *control;
  397. struct bsd_sockaddr *to;
  398. int error;
  399. if (mp->msg_name != NULL) {
  400. to = (struct bsd_sockaddr *)mp->msg_name;
  401. } else {
  402. to = NULL;
  403. }
  404. (void)to; // FIXME: never used?
  405. if (mp->msg_control) {
  406. if (mp->msg_controllen < sizeof(struct cmsghdr)) {
  407. error = EINVAL;
  408. goto bad;
  409. }
  410. error = sockargs(&control, (caddr_t)mp->msg_control,
  411. mp->msg_controllen, MT_CONTROL);
  412. if (error)
  413. goto bad;
  414. } else {
  415. control = NULL;
  416. }
  417. error = kern_sendit(s, mp, flags, control, bytes);
  418. bad:
  419. return (error);
  420. }
  421. int
  422. kern_sendit(int s,
  423. struct msghdr *mp,
  424. int flags,
  425. struct mbuf *control,
  426. ssize_t *bytes)
  427. {
  428. struct file *fp;
  429. struct uio auio = {};
  430. struct iovec *iov;
  431. struct socket *so;
  432. struct bsd_sockaddr *from = 0;
  433. int i, error;
  434. ssize_t len;
  435. error = getsock_cap(s, &fp, NULL);
  436. if (error)
  437. return (error);
  438. so = (struct socket *)file_data(fp);
  439. // Create a local copy of the user's iovec - sosend() is going to change it!
  440. std::vector<iovec> uio_iov(mp->msg_iov, mp->msg_iov + mp->msg_iovlen);
  441. auio.uio_iov = uio_iov.data();
  442. auio.uio_iovcnt = uio_iov.size();
  443. auio.uio_rw = UIO_WRITE;
  444. auio.uio_offset = 0; /* XXX */
  445. auio.uio_resid = 0;
  446. iov = mp->msg_iov;
  447. for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  448. if ((auio.uio_resid += iov->iov_len) < 0) {
  449. error = EINVAL;
  450. goto bad;
  451. }
  452. }
  453. len = auio.uio_resid;
  454. from = (struct bsd_sockaddr*)mp->msg_name;
  455. error = sosend(so, from, &auio, 0, control, flags, 0);
  456. if (error) {
  457. if (auio.uio_resid != len && (error == ERESTART ||
  458. error == EINTR || error == EWOULDBLOCK))
  459. error = 0;
  460. /* FIXME: OSv - Implement... */
  461. #if 0
  462. /* Generation of SIGPIPE can be controlled per socket */
  463. if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
  464. !(flags & MSG_NOSIGNAL)) {
  465. PROC_LOCK(td->td_proc);
  466. tdsignal(td, SIGPIPE);
  467. PROC_UNLOCK(td->td_proc);
  468. }
  469. #endif
  470. }
  471. if (error == 0)
  472. *bytes = len - auio.uio_resid;
  473. bad:
  474. fdrop(fp);
  475. return (error);
  476. }
  477. int
  478. sys_sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen,
  479. ssize_t* bytes)
  480. {
  481. struct msghdr msg = {};
  482. struct iovec aiov = {};
  483. int error;
  484. msg.msg_name = to;
  485. msg.msg_namelen = tolen;
  486. msg.msg_iov = &aiov;
  487. msg.msg_iovlen = 1;
  488. msg.msg_control = 0;
  489. aiov.iov_base = buf;
  490. aiov.iov_len = len;
  491. error = sendit(s, &msg, flags, bytes);
  492. return (error);
  493. }
  494. int
  495. sys_sendmsg(int s, struct msghdr* msg, int flags, ssize_t* bytes)
  496. {
  497. int error;
  498. error = sendit(s, msg, flags, bytes);
  499. return (error);
  500. }
  501. int
  502. kern_recvit(int s, struct msghdr *mp, struct mbuf **controlp, ssize_t* bytes)
  503. {
  504. struct uio auio;
  505. struct iovec *iov;
  506. int i;
  507. ssize_t len;
  508. int error;
  509. struct mbuf *m, *control = 0;
  510. caddr_t ctlbuf;
  511. struct file *fp;
  512. struct socket *so;
  513. struct bsd_sockaddr *fromsa = 0;
  514. if (controlp != NULL)
  515. *controlp = NULL;
  516. error = getsock_cap(s, &fp, NULL);
  517. if (error)
  518. return (error);
  519. so = (socket*)file_data(fp);
  520. auio.uio_iov = mp->msg_iov;
  521. auio.uio_iovcnt = mp->msg_iovlen;
  522. auio.uio_rw = UIO_READ;
  523. auio.uio_offset = 0; /* XXX */
  524. auio.uio_resid = 0;
  525. iov = mp->msg_iov;
  526. for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  527. if ((auio.uio_resid += iov->iov_len) < 0) {
  528. fdrop(fp);
  529. return (EINVAL);
  530. }
  531. }
  532. len = auio.uio_resid;
  533. error = soreceive(so, &fromsa, &auio, (struct mbuf **)0,
  534. (mp->msg_control || controlp) ? &control : (struct mbuf **)0,
  535. &mp->msg_flags);
  536. if (error) {
  537. if (auio.uio_resid != len && (error == ERESTART ||
  538. error == EINTR || error == EWOULDBLOCK))
  539. error = 0;
  540. }
  541. if (error)
  542. goto out;
  543. *bytes = len - auio.uio_resid;
  544. if (mp->msg_name) {
  545. len = mp->msg_namelen;
  546. if (len <= 0 || fromsa == 0)
  547. len = 0;
  548. else {
  549. /* save sa_len before it is destroyed by MSG_COMPAT */
  550. len = MIN(len, fromsa->sa_len);
  551. bcopy(fromsa, mp->msg_name, len);
  552. }
  553. mp->msg_namelen = len;
  554. }
  555. if (mp->msg_control && controlp == NULL) {
  556. len = mp->msg_controllen;
  557. m = control;
  558. mp->msg_controllen = 0;
  559. ctlbuf = (caddr_t)mp->msg_control;
  560. while (m && len > 0) {
  561. unsigned int tocopy;
  562. if (len >= m->m_hdr.mh_len)
  563. tocopy = m->m_hdr.mh_len;
  564. else {
  565. mp->msg_flags |= MSG_CTRUNC;
  566. tocopy = len;
  567. }
  568. if ((error = copyout(mtod(m, caddr_t),
  569. ctlbuf, tocopy)) != 0)
  570. goto out;
  571. ctlbuf += tocopy;
  572. len -= tocopy;
  573. m = m->m_hdr.mh_next;
  574. }
  575. mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
  576. }
  577. out:
  578. fdrop(fp);
  579. if (fromsa)
  580. free(fromsa);
  581. if (error == 0 && controlp != NULL)
  582. *controlp = control;
  583. else if (control)
  584. m_freem(control);
  585. return (error);
  586. }
  587. static int
  588. recvit(int s, struct msghdr *mp, void *namelenp, ssize_t* bytes)
  589. {
  590. int error;
  591. error = kern_recvit(s, mp, NULL, bytes);
  592. if (error)
  593. return (error);
  594. if (namelenp) {
  595. error = copyout(&mp->msg_namelen, namelenp, sizeof (socklen_t));
  596. }
  597. return (error);
  598. }
  599. int
  600. sys_recvfrom(int s, caddr_t buf, size_t len, int flags,
  601. struct bsd_sockaddr * __restrict from,
  602. socklen_t * __restrict fromlenaddr,
  603. ssize_t* bytes)
  604. {
  605. struct msghdr msg;
  606. struct iovec aiov;
  607. int error;
  608. if (fromlenaddr) {
  609. error = copyin(fromlenaddr,
  610. &msg.msg_namelen, sizeof (msg.msg_namelen));
  611. if (error)
  612. goto done2;
  613. } else {
  614. msg.msg_namelen = 0;
  615. }
  616. msg.msg_name = from;
  617. msg.msg_iov = &aiov;
  618. msg.msg_iovlen = 1;
  619. aiov.iov_base = buf;
  620. aiov.iov_len = len;
  621. msg.msg_control = 0;
  622. msg.msg_flags = flags;
  623. error = recvit(s, &msg, fromlenaddr, bytes);
  624. done2:
  625. return(error);
  626. }
  627. int
  628. sys_recvmsg(int s, struct msghdr *msg, int flags, ssize_t* bytes)
  629. {
  630. int error;
  631. msg->msg_flags = flags;
  632. error = recvit(s, msg, NULL, bytes);
  633. return (error);
  634. }
  635. /* ARGSUSED */
  636. int
  637. sys_shutdown(int s, int how)
  638. {
  639. struct socket *so;
  640. struct file *fp;
  641. int error;
  642. error = getsock_cap(s, &fp, NULL);
  643. if (error == 0) {
  644. so = (socket*)file_data(fp);
  645. error = soshutdown(so, how);
  646. fdrop(fp);
  647. }
  648. return (error);
  649. }
  650. /* ARGSUSED */
  651. int
  652. sys_setsockopt(int s, int level, int name, caddr_t val, int valsize)
  653. {
  654. return (kern_setsockopt(s, level, name, val, valsize));
  655. }
  656. int
  657. kern_setsockopt(int s, int level, int name, void *val, socklen_t valsize)
  658. {
  659. int error;
  660. struct socket *so;
  661. struct file *fp;
  662. struct sockopt sopt;
  663. if (val == NULL && valsize != 0)
  664. return (EFAULT);
  665. if ((int)valsize < 0)
  666. return (EINVAL);
  667. sopt.sopt_dir = SOPT_SET;
  668. sopt.sopt_level = level;
  669. sopt.sopt_name = name;
  670. sopt.sopt_val = val;
  671. sopt.sopt_valsize = valsize;
  672. sopt.sopt_td = NULL;
  673. error = getsock_cap(s, &fp, NULL);
  674. if (error == 0) {
  675. so = (socket*)file_data(fp);
  676. error = sosetopt(so, &sopt);
  677. fdrop(fp);
  678. }
  679. return(error);
  680. }
  681. /* ARGSUSED */
  682. int
  683. sys_getsockopt(int s,
  684. int level,
  685. int name,
  686. void * __restrict val,
  687. socklen_t * __restrict avalsize)
  688. {
  689. socklen_t valsize;
  690. int error;
  691. if (val) {
  692. error = copyin(avalsize, &valsize, sizeof (valsize));
  693. if (error)
  694. return (error);
  695. }
  696. error = kern_getsockopt(s, level, name, val, &valsize);
  697. if (error == 0)
  698. error = copyout(&valsize, avalsize, sizeof (valsize));
  699. return (error);
  700. }
  701. /*
  702. * Kernel version of getsockopt.
  703. * optval can be a userland or userspace. optlen is always a kernel pointer.
  704. */
  705. int
  706. kern_getsockopt(int s,
  707. int level,
  708. int name,
  709. void *val,
  710. socklen_t *valsize)
  711. {
  712. int error;
  713. struct socket *so;
  714. struct file *fp;
  715. struct sockopt sopt;
  716. if (val == NULL)
  717. *valsize = 0;
  718. if ((int)*valsize < 0)
  719. return (EINVAL);
  720. sopt.sopt_dir = SOPT_GET;
  721. sopt.sopt_level = level;
  722. sopt.sopt_name = name;
  723. sopt.sopt_val = val;
  724. sopt.sopt_valsize = (size_t)*valsize; /* checked non-negative above */
  725. sopt.sopt_td = NULL;
  726. error = getsock_cap(s, &fp, NULL);
  727. if (error == 0) {
  728. so = (socket*)file_data(fp);
  729. error = sogetopt(so, &sopt);
  730. *valsize = sopt.sopt_valsize;
  731. fdrop(fp);
  732. }
  733. return (error);
  734. }
  735. /*
  736. * getsockname1() - Get socket name.
  737. */
  738. /* ARGSUSED */
  739. int
  740. getsockname1(int fdes, struct bsd_sockaddr * __restrict asa, socklen_t * __restrict alen)
  741. {
  742. struct bsd_sockaddr *sa;
  743. socklen_t len = *alen;
  744. int error;
  745. error = kern_getsockname(fdes, &sa, &len);
  746. if (error) {
  747. *alen = 0;
  748. return (error);
  749. }
  750. *alen = len;
  751. if (len != 0) {
  752. bcopy(sa, asa, len);
  753. }
  754. free(sa);
  755. return (error);
  756. }
  757. int
  758. kern_getsockname(int fd, struct bsd_sockaddr **sa, socklen_t *alen)
  759. {
  760. struct socket *so;
  761. struct file *fp;
  762. socklen_t len;
  763. int error;
  764. if (*alen < 0)
  765. return (EINVAL);
  766. error = getsock_cap(fd, &fp, NULL);
  767. if (error)
  768. return (error);
  769. so = (socket*)file_data(fp);
  770. *sa = NULL;
  771. CURVNET_SET(so->so_vnet);
  772. error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, sa);
  773. CURVNET_RESTORE();
  774. if (error)
  775. goto bad;
  776. if (*sa == NULL)
  777. len = 0;
  778. else
  779. len = MIN(*alen, (*sa)->sa_len);
  780. *alen = len;
  781. #ifdef KTRACE
  782. if (KTRPOINT(td, KTR_STRUCT))
  783. ktrbsd_sockaddr(*sa);
  784. #endif
  785. bad:
  786. fdrop(fp);
  787. if (error && *sa) {
  788. free(*sa);
  789. *sa = NULL;
  790. }
  791. return (error);
  792. }
  793. int
  794. sys_getsockname(int fdes, struct bsd_sockaddr * __restrict asa, socklen_t * __restrict alen)
  795. {
  796. return (getsockname1(fdes, asa, alen));
  797. }
  798. /* FIXME: OSv - Implement getsockopt... */
  799. #if 0
  800. #ifdef COMPAT_OLDSOCK
  801. int
  802. ogetsockname(td, uap)
  803. struct thread *td;
  804. struct getsockname_args *uap;
  805. {
  806. return (getsockname1(td, uap, 1));
  807. }
  808. #endif /* COMPAT_OLDSOCK */
  809. #endif
  810. static int
  811. kern_getpeername(int fd, struct bsd_sockaddr **sa,
  812. socklen_t *alen)
  813. {
  814. struct socket *so;
  815. struct file *fp;
  816. socklen_t len;
  817. int error;
  818. if (*alen < 0)
  819. return (EINVAL);
  820. error = getsock_cap(fd, &fp, NULL);
  821. if (error)
  822. return (error);
  823. so = (socket*)file_data(fp);
  824. if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) {
  825. error = ENOTCONN;
  826. goto done;
  827. }
  828. *sa = NULL;
  829. CURVNET_SET(so->so_vnet);
  830. error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, sa);
  831. CURVNET_RESTORE();
  832. if (error)
  833. goto bad;
  834. if (*sa == NULL)
  835. len = 0;
  836. else
  837. len = MIN(*alen, (*sa)->sa_len);
  838. *alen = len;
  839. bad:
  840. if (error && *sa) {
  841. free(*sa);
  842. *sa = NULL;
  843. }
  844. done:
  845. fdrop(fp);
  846. return (error);
  847. }
  848. int
  849. sys_getpeername(int fdes, struct bsd_sockaddr * __restrict asa, socklen_t * __restrict alen)
  850. {
  851. struct bsd_sockaddr *sa;
  852. socklen_t len;
  853. int error;
  854. error = copyin(alen, &len, sizeof (len));
  855. if (error)
  856. return (error);
  857. error = kern_getpeername(fdes, &sa, &len);
  858. if (error)
  859. return (error);
  860. if (len != 0) {
  861. error = copyout(sa, asa, (u_int)len);
  862. }
  863. free(sa);
  864. if (error == 0)
  865. error = copyout(&len, alen, sizeof(len));
  866. return (error);
  867. }
  868. int
  869. sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type)
  870. {
  871. struct bsd_sockaddr *sa;
  872. struct mbuf *m;
  873. int error;
  874. if ((u_int)buflen > MLEN) {
  875. if ((u_int)buflen > MCLBYTES)
  876. return (EINVAL);
  877. }
  878. m = m_get(M_WAIT, type);
  879. if ((u_int)buflen > MLEN)
  880. MCLGET(m, M_WAIT);
  881. m->m_hdr.mh_len = buflen;
  882. error = copyin(buf, mtod(m, caddr_t), (u_int)buflen);
  883. if (error)
  884. (void) m_free(m);
  885. else {
  886. *mp = m;
  887. if (type == MT_SONAME) {
  888. sa = mtod(m, struct bsd_sockaddr *);
  889. sa->sa_len = buflen;
  890. }
  891. }
  892. return (error);
  893. }
  894. ssize_t
  895. zcopy_tx(int s, struct zmsghdr *zm)
  896. {
  897. struct file *fp;
  898. struct uio auio = {};
  899. struct iovec *iov;
  900. struct socket *so;
  901. int i, error, efd;
  902. ssize_t len;
  903. ssize_t bytes = 0;
  904. auto mp = &zm->zm_msg;
  905. struct ztx_handle *zh = new ztx_handle();
  906. zm->zm_txhandle = zh;
  907. efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
  908. if (efd < 0)
  909. return (efd);
  910. auto close_efd = defer([efd] { close(efd); });
  911. zm->zm_txfd = efd;
  912. error = getsock_cap(s, &fp, NULL);
  913. if (error)
  914. return (error);
  915. so = (struct socket *)file_data(fp);
  916. if (so->so_type != SOCK_STREAM)
  917. return (EINVAL);
  918. // Create a local copy of the user's iovec - sosend() is going to change it!
  919. std::vector<iovec> uio_iov(mp->msg_iov, mp->msg_iov + mp->msg_iovlen);
  920. auio.uio_iov = uio_iov.data();
  921. auio.uio_iovcnt = uio_iov.size();
  922. auio.uio_rw = UIO_WRITE;
  923. auio.uio_offset = 0;
  924. auio.uio_resid = 0;
  925. iov = mp->msg_iov;
  926. for (i = 0; i < mp->msg_iovlen; i++, iov++) {
  927. if ((auio.uio_resid += iov->iov_len) < 0) {
  928. bytes = EINVAL;
  929. goto bad;
  930. }
  931. }
  932. len = auio.uio_resid;
  933. zh->zh_remained = len;
  934. error = zsend(so, &auio, zm, MSG_DONTWAIT);
  935. if (error) {
  936. if (auio.uio_resid != len && (error == ERESTART ||
  937. error == EINTR || error == EWOULDBLOCK))
  938. error = 0;
  939. bytes = error;
  940. }
  941. if (error == 0)
  942. bytes = len - auio.uio_resid;
  943. bad:
  944. fdrop(fp);
  945. if (bytes >= 0) {
  946. close_efd.cancel();
  947. }
  948. return (bytes);
  949. }
  950. void
  951. zcopy_txclose(struct zmsghdr *zm)
  952. {
  953. close(zm->zm_txfd);
  954. }
  955. ssize_t
  956. zcopy_rx(int s, struct zmsghdr *zm)
  957. {
  958. int error;
  959. struct file *fp;
  960. struct socket *so;
  961. struct bsd_sockaddr *fromsa = 0;
  962. int flags = MSG_DONTWAIT;
  963. ssize_t bytes;
  964. error = getsock_cap(s, &fp, NULL);
  965. if (error)
  966. return (error);
  967. so = (socket*)file_data(fp);
  968. if (so->so_type != SOCK_STREAM)
  969. return (EINVAL);
  970. error = zreceive(so, &fromsa, zm, &flags, &bytes);
  971. fdrop(fp);
  972. if (fromsa)
  973. free(fromsa);
  974. if (error) {
  975. errno = error;
  976. return (-1);
  977. }
  978. return (bytes);
  979. }