1/* SPDX-License-Identifier: BSD-3-Clause */
2/*
3 * Copyright (c) 1995 Danny Gasparovski.
4 */
5
6#include "slirp.h"
7#include "ip_icmp.h"
8#ifdef __sun__
9#include <sys/filio.h>
10#endif
11
12static void sofcantrcvmore(struct socket *so);
13static void sofcantsendmore(struct socket *so);
14
15struct socket *solookup(struct socket **last, struct socket *head,
16 struct sockaddr_storage *lhost,
17 struct sockaddr_storage *fhost)
18{
19 struct socket *so = *last;
20
21 /* Optimisation */
22 if (so != head && sockaddr_equal(&(so->lhost.ss), lhost) &&
23 (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
24 return so;
25 }
26
27 for (so = head->so_next; so != head; so = so->so_next) {
28 if (sockaddr_equal(&(so->lhost.ss), lhost) &&
29 (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
30 *last = so;
31 return so;
32 }
33 }
34
35 return (struct socket *)NULL;
36}
37
38/*
39 * Create a new socket, initialise the fields
40 * It is the responsibility of the caller to
41 * insque() it into the correct linked-list
42 */
43struct socket *socreate(Slirp *slirp)
44{
45 struct socket *so = g_new(struct socket, 1);
46
47 memset(so, 0, sizeof(struct socket));
48 so->so_state = SS_NOFDREF;
49 so->s = -1;
50 so->slirp = slirp;
51 so->pollfds_idx = -1;
52
53 return so;
54}
55
56/*
57 * Remove references to so from the given message queue.
58 */
59static void soqfree(struct socket *so, struct quehead *qh)
60{
61 struct mbuf *ifq;
62
63 for (ifq = (struct mbuf *)qh->qh_link; (struct quehead *)ifq != qh;
64 ifq = ifq->ifq_next) {
65 if (ifq->ifq_so == so) {
66 struct mbuf *ifm;
67 ifq->ifq_so = NULL;
68 for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) {
69 ifm->ifq_so = NULL;
70 }
71 }
72 }
73}
74
75/*
76 * remque and free a socket, clobber cache
77 */
78void sofree(struct socket *so)
79{
80 Slirp *slirp = so->slirp;
81
82 soqfree(so, &slirp->if_fastq);
83 soqfree(so, &slirp->if_batchq);
84
85 if (so == slirp->tcp_last_so) {
86 slirp->tcp_last_so = &slirp->tcb;
87 } else if (so == slirp->udp_last_so) {
88 slirp->udp_last_so = &slirp->udb;
89 } else if (so == slirp->icmp_last_so) {
90 slirp->icmp_last_so = &slirp->icmp;
91 }
92 m_free(so->so_m);
93
94 if (so->so_next && so->so_prev)
95 remque(so); /* crashes if so is not in a queue */
96
97 if (so->so_tcpcb) {
98 free(so->so_tcpcb);
99 }
100 g_free(so);
101}
102
103size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
104{
105 int n, lss, total;
106 struct sbuf *sb = &so->so_snd;
107 int len = sb->sb_datalen - sb->sb_cc;
108 int mss = so->so_tcpcb->t_maxseg;
109
110 DEBUG_CALL("sopreprbuf");
111 DEBUG_ARG("so = %p", so);
112
113 if (len <= 0)
114 return 0;
115
116 iov[0].iov_base = sb->sb_wptr;
117 iov[1].iov_base = NULL;
118 iov[1].iov_len = 0;
119 if (sb->sb_wptr < sb->sb_rptr) {
120 iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
121 /* Should never succeed, but... */
122 if (iov[0].iov_len > len)
123 iov[0].iov_len = len;
124 if (iov[0].iov_len > mss)
125 iov[0].iov_len -= iov[0].iov_len % mss;
126 n = 1;
127 } else {
128 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
129 /* Should never succeed, but... */
130 if (iov[0].iov_len > len)
131 iov[0].iov_len = len;
132 len -= iov[0].iov_len;
133 if (len) {
134 iov[1].iov_base = sb->sb_data;
135 iov[1].iov_len = sb->sb_rptr - sb->sb_data;
136 if (iov[1].iov_len > len)
137 iov[1].iov_len = len;
138 total = iov[0].iov_len + iov[1].iov_len;
139 if (total > mss) {
140 lss = total % mss;
141 if (iov[1].iov_len > lss) {
142 iov[1].iov_len -= lss;
143 n = 2;
144 } else {
145 lss -= iov[1].iov_len;
146 iov[0].iov_len -= lss;
147 n = 1;
148 }
149 } else
150 n = 2;
151 } else {
152 if (iov[0].iov_len > mss)
153 iov[0].iov_len -= iov[0].iov_len % mss;
154 n = 1;
155 }
156 }
157 if (np)
158 *np = n;
159
160 return iov[0].iov_len + (n - 1) * iov[1].iov_len;
161}
162
163/*
164 * Read from so's socket into sb_snd, updating all relevant sbuf fields
165 * NOTE: This will only be called if it is select()ed for reading, so
166 * a read() of 0 (or less) means it's disconnected
167 */
168int soread(struct socket *so)
169{
170 int n, nn;
171 size_t buf_len;
172 struct sbuf *sb = &so->so_snd;
173 struct iovec iov[2];
174
175 DEBUG_CALL("soread");
176 DEBUG_ARG("so = %p", so);
177
178 /*
179 * No need to check if there's enough room to read.
180 * soread wouldn't have been called if there weren't
181 */
182 buf_len = sopreprbuf(so, iov, &n);
183 assert(buf_len != 0);
184
185 nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, 0);
186 if (nn <= 0) {
187 if (nn < 0 && (errno == EINTR || errno == EAGAIN))
188 return 0;
189 else {
190 int err;
191 socklen_t elen = sizeof err;
192 struct sockaddr_storage addr;
193 struct sockaddr *paddr = (struct sockaddr *)&addr;
194 socklen_t alen = sizeof addr;
195
196 err = errno;
197 if (nn == 0) {
198 if (getpeername(so->s, paddr, &alen) < 0) {
199 err = errno;
200 } else {
201 getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &elen);
202 }
203 }
204
205 DEBUG_MISC(" --- soread() disconnected, nn = %d, errno = %d-%s", nn,
206 errno, strerror(errno));
207 sofcantrcvmore(so);
208
209 if (err == ECONNRESET || err == ECONNREFUSED || err == ENOTCONN ||
210 err == EPIPE) {
211 tcp_drop(sototcpcb(so), err);
212 } else {
213 tcp_sockclosed(sototcpcb(so));
214 }
215 return -1;
216 }
217 }
218
219 /*
220 * If there was no error, try and read the second time round
221 * We read again if n = 2 (ie, there's another part of the buffer)
222 * and we read as much as we could in the first read
223 * We don't test for <= 0 this time, because there legitimately
224 * might not be any more data (since the socket is non-blocking),
225 * a close will be detected on next iteration.
226 * A return of -1 won't (shouldn't) happen, since it didn't happen above
227 */
228 if (n == 2 && nn == iov[0].iov_len) {
229 int ret;
230 ret = recv(so->s, iov[1].iov_base, iov[1].iov_len, 0);
231 if (ret > 0)
232 nn += ret;
233 }
234
235 DEBUG_MISC(" ... read nn = %d bytes", nn);
236
237 /* Update fields */
238 sb->sb_cc += nn;
239 sb->sb_wptr += nn;
240 if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
241 sb->sb_wptr -= sb->sb_datalen;
242 return nn;
243}
244
245int soreadbuf(struct socket *so, const char *buf, int size)
246{
247 int n, nn, copy = size;
248 struct sbuf *sb = &so->so_snd;
249 struct iovec iov[2];
250
251 DEBUG_CALL("soreadbuf");
252 DEBUG_ARG("so = %p", so);
253
254 /*
255 * No need to check if there's enough room to read.
256 * soread wouldn't have been called if there weren't
257 */
258 assert(size > 0);
259 if (sopreprbuf(so, iov, &n) < size)
260 goto err;
261
262 nn = MIN(iov[0].iov_len, copy);
263 memcpy(iov[0].iov_base, buf, nn);
264
265 copy -= nn;
266 buf += nn;
267
268 if (copy == 0)
269 goto done;
270
271 memcpy(iov[1].iov_base, buf, copy);
272
273done:
274 /* Update fields */
275 sb->sb_cc += size;
276 sb->sb_wptr += size;
277 if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
278 sb->sb_wptr -= sb->sb_datalen;
279 return size;
280err:
281
282 sofcantrcvmore(so);
283 tcp_sockclosed(sototcpcb(so));
284 g_critical("soreadbuf buffer too small");
285 return -1;
286}
287
288/*
289 * Get urgent data
290 *
291 * When the socket is created, we set it SO_OOBINLINE,
292 * so when OOB data arrives, we soread() it and everything
293 * in the send buffer is sent as urgent data
294 */
295int sorecvoob(struct socket *so)
296{
297 struct tcpcb *tp = sototcpcb(so);
298 int ret;
299
300 DEBUG_CALL("sorecvoob");
301 DEBUG_ARG("so = %p", so);
302
303 /*
304 * We take a guess at how much urgent data has arrived.
305 * In most situations, when urgent data arrives, the next
306 * read() should get all the urgent data. This guess will
307 * be wrong however if more data arrives just after the
308 * urgent data, or the read() doesn't return all the
309 * urgent data.
310 */
311 ret = soread(so);
312 if (ret > 0) {
313 tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
314 tp->t_force = 1;
315 tcp_output(tp);
316 tp->t_force = 0;
317 }
318
319 return ret;
320}
321
322/*
323 * Send urgent data
324 * There's a lot duplicated code here, but...
325 */
326int sosendoob(struct socket *so)
327{
328 struct sbuf *sb = &so->so_rcv;
329 char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
330
331 int n;
332
333 DEBUG_CALL("sosendoob");
334 DEBUG_ARG("so = %p", so);
335 DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
336
337 if (so->so_urgc > 2048)
338 so->so_urgc = 2048; /* XXXX */
339
340 if (sb->sb_rptr < sb->sb_wptr) {
341 /* We can send it directly */
342 n = slirp_send(so, sb->sb_rptr, so->so_urgc,
343 (MSG_OOB)); /* |MSG_DONTWAIT)); */
344 } else {
345 /*
346 * Since there's no sendv or sendtov like writev,
347 * we must copy all data to a linear buffer then
348 * send it all
349 */
350 uint32_t urgc = so->so_urgc;
351 int len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
352 if (len > urgc) {
353 len = urgc;
354 }
355 memcpy(buff, sb->sb_rptr, len);
356 urgc -= len;
357 if (urgc) {
358 n = sb->sb_wptr - sb->sb_data;
359 if (n > urgc) {
360 n = urgc;
361 }
362 memcpy((buff + len), sb->sb_data, n);
363 len += n;
364 }
365 n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
366#ifdef DEBUG
367 if (n != len) {
368 DEBUG_ERROR("Didn't send all data urgently XXXXX");
369 }
370#endif
371 }
372
373 if (n < 0) {
374 return n;
375 }
376 so->so_urgc -= n;
377 DEBUG_MISC(" ---2 sent %d bytes urgent data, %d urgent bytes left", n,
378 so->so_urgc);
379
380 sb->sb_cc -= n;
381 sb->sb_rptr += n;
382 if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
383 sb->sb_rptr -= sb->sb_datalen;
384
385 return n;
386}
387
388/*
389 * Write data from so_rcv to so's socket,
390 * updating all sbuf field as necessary
391 */
392int sowrite(struct socket *so)
393{
394 int n, nn;
395 struct sbuf *sb = &so->so_rcv;
396 int len = sb->sb_cc;
397 struct iovec iov[2];
398
399 DEBUG_CALL("sowrite");
400 DEBUG_ARG("so = %p", so);
401
402 if (so->so_urgc) {
403 uint32_t expected = so->so_urgc;
404 if (sosendoob(so) < expected) {
405 /* Treat a short write as a fatal error too,
406 * rather than continuing on and sending the urgent
407 * data as if it were non-urgent and leaving the
408 * so_urgc count wrong.
409 */
410 goto err_disconnected;
411 }
412 if (sb->sb_cc == 0)
413 return 0;
414 }
415
416 /*
417 * No need to check if there's something to write,
418 * sowrite wouldn't have been called otherwise
419 */
420
421 iov[0].iov_base = sb->sb_rptr;
422 iov[1].iov_base = NULL;
423 iov[1].iov_len = 0;
424 if (sb->sb_rptr < sb->sb_wptr) {
425 iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
426 /* Should never succeed, but... */
427 if (iov[0].iov_len > len)
428 iov[0].iov_len = len;
429 n = 1;
430 } else {
431 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
432 if (iov[0].iov_len > len)
433 iov[0].iov_len = len;
434 len -= iov[0].iov_len;
435 if (len) {
436 iov[1].iov_base = sb->sb_data;
437 iov[1].iov_len = sb->sb_wptr - sb->sb_data;
438 if (iov[1].iov_len > len)
439 iov[1].iov_len = len;
440 n = 2;
441 } else
442 n = 1;
443 }
444 /* Check if there's urgent data to send, and if so, send it */
445
446 nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len, 0);
447 /* This should never happen, but people tell me it does *shrug* */
448 if (nn < 0 && (errno == EAGAIN || errno == EINTR))
449 return 0;
450
451 if (nn <= 0) {
452 goto err_disconnected;
453 }
454
455 if (n == 2 && nn == iov[0].iov_len) {
456 int ret;
457 ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len, 0);
458 if (ret > 0)
459 nn += ret;
460 }
461 DEBUG_MISC(" ... wrote nn = %d bytes", nn);
462
463 /* Update sbuf */
464 sb->sb_cc -= nn;
465 sb->sb_rptr += nn;
466 if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
467 sb->sb_rptr -= sb->sb_datalen;
468
469 /*
470 * If in DRAIN mode, and there's no more data, set
471 * it CANTSENDMORE
472 */
473 if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
474 sofcantsendmore(so);
475
476 return nn;
477
478err_disconnected:
479 DEBUG_MISC(" --- sowrite disconnected, so->so_state = %x, errno = %d",
480 so->so_state, errno);
481 sofcantsendmore(so);
482 tcp_sockclosed(sototcpcb(so));
483 return -1;
484}
485
486/*
487 * recvfrom() a UDP socket
488 */
489void sorecvfrom(struct socket *so)
490{
491 struct sockaddr_storage addr;
492 struct sockaddr_storage saddr, daddr;
493 socklen_t addrlen = sizeof(struct sockaddr_storage);
494
495 DEBUG_CALL("sorecvfrom");
496 DEBUG_ARG("so = %p", so);
497
498 if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
499 char buff[256];
500 int len;
501
502 len = recvfrom(so->s, buff, 256, 0, (struct sockaddr *)&addr, &addrlen);
503 /* XXX Check if reply is "correct"? */
504
505 if (len == -1 || len == 0) {
506 uint8_t code = ICMP_UNREACH_PORT;
507
508 if (errno == EHOSTUNREACH)
509 code = ICMP_UNREACH_HOST;
510 else if (errno == ENETUNREACH)
511 code = ICMP_UNREACH_NET;
512
513 DEBUG_MISC(" udp icmp rx errno = %d-%s", errno, strerror(errno));
514 icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
515 } else {
516 icmp_reflect(so->so_m);
517 so->so_m = NULL; /* Don't m_free() it again! */
518 }
519 /* No need for this socket anymore, udp_detach it */
520 udp_detach(so);
521 } else { /* A "normal" UDP packet */
522 struct mbuf *m;
523 int len;
524#ifdef _WIN32
525 unsigned long n;
526#else
527 int n;
528#endif
529
530 if (ioctlsocket(so->s, FIONREAD, &n) != 0) {
531 DEBUG_MISC(" ioctlsocket errno = %d-%s\n", errno, strerror(errno));
532 return;
533 }
534 if (n == 0) {
535 return;
536 }
537
538 m = m_get(so->slirp);
539 if (!m) {
540 return;
541 }
542 switch (so->so_ffamily) {
543 case AF_INET:
544 m->m_data += IF_MAXLINKHDR + sizeof(struct udpiphdr);
545 break;
546 case AF_INET6:
547 m->m_data +=
548 IF_MAXLINKHDR + sizeof(struct ip6) + sizeof(struct udphdr);
549 break;
550 default:
551 g_assert_not_reached();
552 break;
553 }
554
555 /*
556 * XXX Shouldn't FIONREAD packets destined for port 53,
557 * but I don't know the max packet size for DNS lookups
558 */
559 len = M_FREEROOM(m);
560 /* if (so->so_fport != htons(53)) { */
561
562 if (n > len) {
563 n = (m->m_data - m->m_dat) + m->m_len + n + 1;
564 m_inc(m, n);
565 len = M_FREEROOM(m);
566 }
567 /* } */
568
569 m->m_len = recvfrom(so->s, m->m_data, len, 0, (struct sockaddr *)&addr,
570 &addrlen);
571 DEBUG_MISC(" did recvfrom %d, errno = %d-%s", m->m_len, errno,
572 strerror(errno));
573 if (m->m_len < 0) {
574 /* Report error as ICMP */
575 switch (so->so_lfamily) {
576 uint8_t code;
577 case AF_INET:
578 code = ICMP_UNREACH_PORT;
579
580 if (errno == EHOSTUNREACH) {
581 code = ICMP_UNREACH_HOST;
582 } else if (errno == ENETUNREACH) {
583 code = ICMP_UNREACH_NET;
584 }
585
586 DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code);
587 icmp_send_error(so->so_m, ICMP_UNREACH, code, 0,
588 strerror(errno));
589 break;
590 case AF_INET6:
591 code = ICMP6_UNREACH_PORT;
592
593 if (errno == EHOSTUNREACH) {
594 code = ICMP6_UNREACH_ADDRESS;
595 } else if (errno == ENETUNREACH) {
596 code = ICMP6_UNREACH_NO_ROUTE;
597 }
598
599 DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
600 icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
601 break;
602 default:
603 g_assert_not_reached();
604 break;
605 }
606 m_free(m);
607 } else {
608 /*
609 * Hack: domain name lookup will be used the most for UDP,
610 * and since they'll only be used once there's no need
611 * for the 4 minute (or whatever) timeout... So we time them
612 * out much quicker (10 seconds for now...)
613 */
614 if (so->so_expire) {
615 if (so->so_fport == htons(53))
616 so->so_expire = curtime + SO_EXPIREFAST;
617 else
618 so->so_expire = curtime + SO_EXPIRE;
619 }
620
621 /*
622 * If this packet was destined for CTL_ADDR,
623 * make it look like that's where it came from
624 */
625 saddr = addr;
626 sotranslate_in(so, &saddr);
627 daddr = so->lhost.ss;
628
629 switch (so->so_ffamily) {
630 case AF_INET:
631 udp_output(so, m, (struct sockaddr_in *)&saddr,
632 (struct sockaddr_in *)&daddr, so->so_iptos);
633 break;
634 case AF_INET6:
635 udp6_output(so, m, (struct sockaddr_in6 *)&saddr,
636 (struct sockaddr_in6 *)&daddr);
637 break;
638 default:
639 g_assert_not_reached();
640 break;
641 }
642 } /* rx error */
643 } /* if ping packet */
644}
645
646/*
647 * sendto() a socket
648 */
649int sosendto(struct socket *so, struct mbuf *m)
650{
651 int ret;
652 struct sockaddr_storage addr;
653
654 DEBUG_CALL("sosendto");
655 DEBUG_ARG("so = %p", so);
656 DEBUG_ARG("m = %p", m);
657
658 addr = so->fhost.ss;
659 DEBUG_CALL(" sendto()ing)");
660 sotranslate_out(so, &addr);
661
662 /* Don't care what port we get */
663 ret = sendto(so->s, m->m_data, m->m_len, 0, (struct sockaddr *)&addr,
664 sockaddr_size(&addr));
665 if (ret < 0)
666 return -1;
667
668 /*
669 * Kill the socket if there's no reply in 4 minutes,
670 * but only if it's an expirable socket
671 */
672 if (so->so_expire)
673 so->so_expire = curtime + SO_EXPIRE;
674 so->so_state &= SS_PERSISTENT_MASK;
675 so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
676 return 0;
677}
678
679/*
680 * Listen for incoming TCP connections
681 */
682struct socket *tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport,
683 uint32_t laddr, unsigned lport, int flags)
684{
685 /* TODO: IPv6 */
686 struct sockaddr_in addr;
687 struct socket *so;
688 int s, opt = 1;
689 socklen_t addrlen = sizeof(addr);
690 memset(&addr, 0, addrlen);
691
692 DEBUG_CALL("tcp_listen");
693 DEBUG_ARG("haddr = %s", inet_ntoa((struct in_addr){ .s_addr = haddr }));
694 DEBUG_ARG("hport = %d", ntohs(hport));
695 DEBUG_ARG("laddr = %s", inet_ntoa((struct in_addr){ .s_addr = laddr }));
696 DEBUG_ARG("lport = %d", ntohs(lport));
697 DEBUG_ARG("flags = %x", flags);
698
699 so = socreate(slirp);
700
701 /* Don't tcp_attach... we don't need so_snd nor so_rcv */
702 if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
703 g_free(so);
704 return NULL;
705 }
706 insque(so, &slirp->tcb);
707
708 /*
709 * SS_FACCEPTONCE sockets must time out.
710 */
711 if (flags & SS_FACCEPTONCE)
712 so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT * 2;
713
714 so->so_state &= SS_PERSISTENT_MASK;
715 so->so_state |= (SS_FACCEPTCONN | flags);
716 so->so_lfamily = AF_INET;
717 so->so_lport = lport; /* Kept in network format */
718 so->so_laddr.s_addr = laddr; /* Ditto */
719
720 addr.sin_family = AF_INET;
721 addr.sin_addr.s_addr = haddr;
722 addr.sin_port = hport;
723
724 if (((s = slirp_socket(AF_INET, SOCK_STREAM, 0)) < 0) ||
725 (slirp_socket_set_fast_reuse(s) < 0) ||
726 (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) ||
727 (listen(s, 1) < 0)) {
728 int tmperrno = errno; /* Don't clobber the real reason we failed */
729
730 if (s >= 0) {
731 closesocket(s);
732 }
733 sofree(so);
734 /* Restore the real errno */
735#ifdef _WIN32
736 WSASetLastError(tmperrno);
737#else
738 errno = tmperrno;
739#endif
740 return NULL;
741 }
742 setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
743 opt = 1;
744 setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
745
746 getsockname(s, (struct sockaddr *)&addr, &addrlen);
747 so->so_ffamily = AF_INET;
748 so->so_fport = addr.sin_port;
749 if (addr.sin_addr.s_addr == 0 ||
750 addr.sin_addr.s_addr == loopback_addr.s_addr)
751 so->so_faddr = slirp->vhost_addr;
752 else
753 so->so_faddr = addr.sin_addr;
754
755 so->s = s;
756 return so;
757}
758
759/*
760 * Various session state calls
761 * XXX Should be #define's
762 * The socket state stuff needs work, these often get call 2 or 3
763 * times each when only 1 was needed
764 */
765void soisfconnecting(struct socket *so)
766{
767 so->so_state &= ~(SS_NOFDREF | SS_ISFCONNECTED | SS_FCANTRCVMORE |
768 SS_FCANTSENDMORE | SS_FWDRAIN);
769 so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
770}
771
772void soisfconnected(struct socket *so)
773{
774 so->so_state &= ~(SS_ISFCONNECTING | SS_FWDRAIN | SS_NOFDREF);
775 so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
776}
777
778static void sofcantrcvmore(struct socket *so)
779{
780 if ((so->so_state & SS_NOFDREF) == 0) {
781 shutdown(so->s, 0);
782 }
783 so->so_state &= ~(SS_ISFCONNECTING);
784 if (so->so_state & SS_FCANTSENDMORE) {
785 so->so_state &= SS_PERSISTENT_MASK;
786 so->so_state |= SS_NOFDREF; /* Don't select it */
787 } else {
788 so->so_state |= SS_FCANTRCVMORE;
789 }
790}
791
792static void sofcantsendmore(struct socket *so)
793{
794 if ((so->so_state & SS_NOFDREF) == 0) {
795 shutdown(so->s, 1); /* send FIN to fhost */
796 }
797 so->so_state &= ~(SS_ISFCONNECTING);
798 if (so->so_state & SS_FCANTRCVMORE) {
799 so->so_state &= SS_PERSISTENT_MASK;
800 so->so_state |= SS_NOFDREF; /* as above */
801 } else {
802 so->so_state |= SS_FCANTSENDMORE;
803 }
804}
805
806/*
807 * Set write drain mode
808 * Set CANTSENDMORE once all data has been write()n
809 */
810void sofwdrain(struct socket *so)
811{
812 if (so->so_rcv.sb_cc)
813 so->so_state |= SS_FWDRAIN;
814 else
815 sofcantsendmore(so);
816}
817
818/*
819 * Translate addr in host addr when it is a virtual address
820 */
821void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
822{
823 Slirp *slirp = so->slirp;
824 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
825 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
826
827 switch (addr->ss_family) {
828 case AF_INET:
829 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
830 slirp->vnetwork_addr.s_addr) {
831 /* It's an alias */
832 if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
833 if (get_dns_addr(&sin->sin_addr) < 0) {
834 sin->sin_addr = loopback_addr;
835 }
836 } else {
837 sin->sin_addr = loopback_addr;
838 }
839 }
840
841 DEBUG_MISC(" addr.sin_port=%d, addr.sin_addr.s_addr=%.16s",
842 ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
843 break;
844
845 case AF_INET6:
846 if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
847 slirp->vprefix_len)) {
848 if (in6_equal(&so->so_faddr6, &slirp->vnameserver_addr6)) {
849 uint32_t scope_id;
850 if (get_dns6_addr(&sin6->sin6_addr, &scope_id) >= 0) {
851 sin6->sin6_scope_id = scope_id;
852 } else {
853 sin6->sin6_addr = in6addr_loopback;
854 }
855 } else {
856 sin6->sin6_addr = in6addr_loopback;
857 }
858 }
859 break;
860
861 default:
862 break;
863 }
864}
865
866void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
867{
868 Slirp *slirp = so->slirp;
869 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
870 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
871
872 switch (addr->ss_family) {
873 case AF_INET:
874 if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
875 slirp->vnetwork_addr.s_addr) {
876 uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
877
878 if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
879 sin->sin_addr = slirp->vhost_addr;
880 } else if (sin->sin_addr.s_addr == loopback_addr.s_addr ||
881 so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
882 sin->sin_addr = so->so_faddr;
883 }
884 }
885 break;
886
887 case AF_INET6:
888 if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
889 slirp->vprefix_len)) {
890 if (in6_equal(&sin6->sin6_addr, &in6addr_loopback) ||
891 !in6_equal(&so->so_faddr6, &slirp->vhost_addr6)) {
892 sin6->sin6_addr = so->so_faddr6;
893 }
894 }
895 break;
896
897 default:
898 break;
899 }
900}
901
902/*
903 * Translate connections from localhost to the real hostname
904 */
905void sotranslate_accept(struct socket *so)
906{
907 Slirp *slirp = so->slirp;
908
909 switch (so->so_ffamily) {
910 case AF_INET:
911 if (so->so_faddr.s_addr == INADDR_ANY ||
912 (so->so_faddr.s_addr & loopback_mask) ==
913 (loopback_addr.s_addr & loopback_mask)) {
914 so->so_faddr = slirp->vhost_addr;
915 }
916 break;
917
918 case AF_INET6:
919 if (in6_equal(&so->so_faddr6, &in6addr_any) ||
920 in6_equal(&so->so_faddr6, &in6addr_loopback)) {
921 so->so_faddr6 = slirp->vhost_addr6;
922 }
923 break;
924
925 default:
926 break;
927 }
928}
929
930void sodrop(struct socket *s, int num)
931{
932 if (sbdrop(&s->so_snd, num)) {
933 s->slirp->cb->notify(s->slirp->opaque);
934 }
935}
936