Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/libslirp/socket.c
2 views
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
#ifdef __linux__
12
#include <linux/errqueue.h>
13
#endif
14
15
static void sofcantrcvmore(struct socket *so);
16
static void sofcantsendmore(struct socket *so);
17
18
struct socket *solookup(struct socket **last, struct socket *head,
19
struct sockaddr_storage *lhost,
20
struct sockaddr_storage *fhost)
21
{
22
struct socket *so = *last;
23
24
/* Optimisation */
25
if (so != head && sockaddr_equal(&(so->lhost.ss), lhost) &&
26
(!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
27
return so;
28
}
29
30
for (so = head->so_next; so != head; so = so->so_next) {
31
if (sockaddr_equal(&(so->lhost.ss), lhost) &&
32
(!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
33
*last = so;
34
return so;
35
}
36
}
37
38
return (struct socket *)NULL;
39
}
40
41
/*
42
* Create a new socket, initialise the fields
43
* It is the responsibility of the caller to
44
* slirp_insque() it into the correct linked-list
45
*/
46
struct socket *socreate(Slirp *slirp, int type)
47
{
48
struct socket *so = g_new(struct socket, 1);
49
50
memset(so, 0, sizeof(struct socket));
51
so->so_type = type;
52
so->so_state = SS_NOFDREF;
53
so->s = -1;
54
so->s_aux = -1;
55
so->slirp = slirp;
56
so->pollfds_idx = -1;
57
58
return so;
59
}
60
61
/*
62
* Remove references to so from the given message queue.
63
*/
64
static void soqfree(struct socket *so, struct slirp_quehead *qh)
65
{
66
struct mbuf *ifq;
67
68
for (ifq = (struct mbuf *)qh->qh_link; (struct slirp_quehead *)ifq != qh;
69
ifq = ifq->m_next) {
70
if (ifq->m_so == so) {
71
struct mbuf *ifm;
72
ifq->m_so = NULL;
73
for (ifm = ifq->m_nextpkt; ifm != ifq; ifm = ifm->m_nextpkt) {
74
ifm->m_so = NULL;
75
}
76
}
77
}
78
}
79
80
/*
81
* slirp_remque and free a socket, clobber cache
82
*/
83
void sofree(struct socket *so)
84
{
85
Slirp *slirp = so->slirp;
86
87
if (so->s_aux != -1) {
88
closesocket(so->s_aux);
89
}
90
91
soqfree(so, &slirp->if_fastq);
92
soqfree(so, &slirp->if_batchq);
93
94
if (so == slirp->tcp_last_so) {
95
slirp->tcp_last_so = &slirp->tcb;
96
} else if (so == slirp->udp_last_so) {
97
slirp->udp_last_so = &slirp->udb;
98
} else if (so == slirp->icmp_last_so) {
99
slirp->icmp_last_so = &slirp->icmp;
100
}
101
m_free(so->so_m);
102
103
if (so->so_next && so->so_prev)
104
slirp_remque(so); /* crashes if so is not in a queue */
105
106
if (so->so_tcpcb) {
107
g_free(so->so_tcpcb);
108
}
109
g_free(so);
110
}
111
112
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
113
{
114
int n, lss, total;
115
struct sbuf *sb = &so->so_snd;
116
int len = sb->sb_datalen - sb->sb_cc;
117
int mss = so->so_tcpcb->t_maxseg;
118
119
DEBUG_CALL("sopreprbuf");
120
DEBUG_ARG("so = %p", so);
121
122
if (len <= 0)
123
return 0;
124
125
iov[0].iov_base = sb->sb_wptr;
126
iov[1].iov_base = NULL;
127
iov[1].iov_len = 0;
128
if (sb->sb_wptr < sb->sb_rptr) {
129
iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
130
/* Should never succeed, but... */
131
if (iov[0].iov_len > len)
132
iov[0].iov_len = len;
133
if (iov[0].iov_len > mss)
134
iov[0].iov_len -= iov[0].iov_len % mss;
135
n = 1;
136
} else {
137
iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
138
/* Should never succeed, but... */
139
if (iov[0].iov_len > len)
140
iov[0].iov_len = len;
141
len -= iov[0].iov_len;
142
if (len) {
143
iov[1].iov_base = sb->sb_data;
144
iov[1].iov_len = sb->sb_rptr - sb->sb_data;
145
if (iov[1].iov_len > len)
146
iov[1].iov_len = len;
147
total = iov[0].iov_len + iov[1].iov_len;
148
if (total > mss) {
149
lss = total % mss;
150
if (iov[1].iov_len > lss) {
151
iov[1].iov_len -= lss;
152
n = 2;
153
} else {
154
lss -= iov[1].iov_len;
155
iov[0].iov_len -= lss;
156
n = 1;
157
}
158
} else
159
n = 2;
160
} else {
161
if (iov[0].iov_len > mss)
162
iov[0].iov_len -= iov[0].iov_len % mss;
163
n = 1;
164
}
165
}
166
if (np)
167
*np = n;
168
169
return iov[0].iov_len + (n - 1) * iov[1].iov_len;
170
}
171
172
/*
173
* Read from so's socket into sb_snd, updating all relevant sbuf fields
174
* NOTE: This will only be called if it is select()ed for reading, so
175
* a read() of 0 (or less) means it's disconnected
176
*/
177
int soread(struct socket *so)
178
{
179
int n, nn;
180
size_t buf_len;
181
struct sbuf *sb = &so->so_snd;
182
struct iovec iov[2];
183
184
DEBUG_CALL("soread");
185
DEBUG_ARG("so = %p", so);
186
187
/*
188
* No need to check if there's enough room to read.
189
* soread wouldn't have been called if there weren't
190
*/
191
buf_len = sopreprbuf(so, iov, &n);
192
assert(buf_len != 0);
193
194
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, 0);
195
if (nn <= 0) {
196
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
197
return 0;
198
else {
199
int err;
200
socklen_t elen = sizeof err;
201
struct sockaddr_storage addr;
202
struct sockaddr *paddr = (struct sockaddr *)&addr;
203
socklen_t alen = sizeof addr;
204
205
err = errno;
206
if (nn == 0) {
207
int shutdown_wr = so->so_state & SS_FCANTSENDMORE;
208
209
if (!shutdown_wr && getpeername(so->s, paddr, &alen) < 0) {
210
err = errno;
211
} else {
212
getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &elen);
213
}
214
}
215
216
DEBUG_MISC(" --- soread() disconnected, nn = %d, errno = %d-%s", nn,
217
errno, strerror(errno));
218
sofcantrcvmore(so);
219
220
if (err == ECONNABORTED || err == ECONNRESET || err == ECONNREFUSED ||
221
err == ENOTCONN || err == EPIPE) {
222
tcp_drop(sototcpcb(so), err);
223
} else {
224
tcp_sockclosed(sototcpcb(so));
225
}
226
return -1;
227
}
228
}
229
230
/*
231
* If there was no error, try and read the second time round
232
* We read again if n = 2 (ie, there's another part of the buffer)
233
* and we read as much as we could in the first read
234
* We don't test for <= 0 this time, because there legitimately
235
* might not be any more data (since the socket is non-blocking),
236
* a close will be detected on next iteration.
237
* A return of -1 won't (shouldn't) happen, since it didn't happen above
238
*/
239
if (n == 2 && nn == iov[0].iov_len) {
240
int ret;
241
ret = recv(so->s, iov[1].iov_base, iov[1].iov_len, 0);
242
if (ret > 0)
243
nn += ret;
244
}
245
246
DEBUG_MISC(" ... read nn = %d bytes", nn);
247
248
/* Update fields */
249
sb->sb_cc += nn;
250
sb->sb_wptr += nn;
251
if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
252
sb->sb_wptr -= sb->sb_datalen;
253
return nn;
254
}
255
256
int soreadbuf(struct socket *so, const char *buf, int size)
257
{
258
int n, nn, copy = size;
259
struct sbuf *sb = &so->so_snd;
260
struct iovec iov[2];
261
262
DEBUG_CALL("soreadbuf");
263
DEBUG_ARG("so = %p", so);
264
265
/*
266
* No need to check if there's enough room to read.
267
* soread wouldn't have been called if there weren't
268
*/
269
assert(size > 0);
270
if (sopreprbuf(so, iov, &n) < size)
271
goto err;
272
273
nn = MIN(iov[0].iov_len, copy);
274
memcpy(iov[0].iov_base, buf, nn);
275
276
copy -= nn;
277
buf += nn;
278
279
if (copy == 0)
280
goto done;
281
282
memcpy(iov[1].iov_base, buf, copy);
283
284
done:
285
/* Update fields */
286
sb->sb_cc += size;
287
sb->sb_wptr += size;
288
if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
289
sb->sb_wptr -= sb->sb_datalen;
290
return size;
291
err:
292
293
sofcantrcvmore(so);
294
tcp_sockclosed(sototcpcb(so));
295
g_critical("soreadbuf buffer too small");
296
return -1;
297
}
298
299
/*
300
* Get urgent data
301
*
302
* When the socket is created, we set it SO_OOBINLINE,
303
* so when OOB data arrives, we soread() it and everything
304
* in the send buffer is sent as urgent data
305
*/
306
int sorecvoob(struct socket *so)
307
{
308
struct tcpcb *tp = sototcpcb(so);
309
int ret;
310
311
DEBUG_CALL("sorecvoob");
312
DEBUG_ARG("so = %p", so);
313
314
/*
315
* We take a guess at how much urgent data has arrived.
316
* In most situations, when urgent data arrives, the next
317
* read() should get all the urgent data. This guess will
318
* be wrong however if more data arrives just after the
319
* urgent data, or the read() doesn't return all the
320
* urgent data.
321
*/
322
ret = soread(so);
323
if (ret > 0) {
324
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
325
tp->t_force = 1;
326
tcp_output(tp);
327
tp->t_force = 0;
328
}
329
330
return ret;
331
}
332
333
/*
334
* Send urgent data
335
* There's a lot duplicated code here, but...
336
*/
337
int sosendoob(struct socket *so)
338
{
339
struct sbuf *sb = &so->so_rcv;
340
char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
341
342
int n;
343
344
DEBUG_CALL("sosendoob");
345
DEBUG_ARG("so = %p", so);
346
DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
347
348
if (so->so_urgc > sizeof(buff))
349
so->so_urgc = sizeof(buff); /* XXXX */
350
351
if (sb->sb_rptr < sb->sb_wptr) {
352
/* We can send it directly */
353
n = slirp_send(so, sb->sb_rptr, so->so_urgc,
354
(MSG_OOB)); /* |MSG_DONTWAIT)); */
355
} else {
356
/*
357
* Since there's no sendv or sendtov like writev,
358
* we must copy all data to a linear buffer then
359
* send it all
360
*/
361
uint32_t urgc = so->so_urgc; /* Amount of room left in buff */
362
int len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
363
if (len > urgc) {
364
len = urgc;
365
}
366
memcpy(buff, sb->sb_rptr, len);
367
urgc -= len;
368
if (urgc) {
369
/* We still have some room for the rest */
370
n = sb->sb_wptr - sb->sb_data;
371
if (n > urgc) {
372
n = urgc;
373
}
374
memcpy((buff + len), sb->sb_data, n);
375
len += n;
376
}
377
n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
378
#ifdef SLIRP_DEBUG
379
if (n != len) {
380
DEBUG_ERROR("Didn't send all data urgently XXXXX");
381
}
382
#endif
383
}
384
385
if (n < 0) {
386
return n;
387
}
388
so->so_urgc -= n;
389
DEBUG_MISC(" ---2 sent %d bytes urgent data, %d urgent bytes left", n,
390
so->so_urgc);
391
392
sb->sb_cc -= n;
393
sb->sb_rptr += n;
394
if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
395
sb->sb_rptr -= sb->sb_datalen;
396
397
return n;
398
}
399
400
/*
401
* Write data from so_rcv to so's socket,
402
* updating all sbuf field as necessary
403
*/
404
int sowrite(struct socket *so)
405
{
406
int n, nn;
407
struct sbuf *sb = &so->so_rcv;
408
int len = sb->sb_cc;
409
struct iovec iov[2];
410
411
DEBUG_CALL("sowrite");
412
DEBUG_ARG("so = %p", so);
413
414
if (so->so_urgc) {
415
uint32_t expected = so->so_urgc;
416
if (sosendoob(so) < expected) {
417
/* Treat a short write as a fatal error too,
418
* rather than continuing on and sending the urgent
419
* data as if it were non-urgent and leaving the
420
* so_urgc count wrong.
421
*/
422
goto err_disconnected;
423
}
424
if (sb->sb_cc == 0)
425
return 0;
426
}
427
428
/*
429
* No need to check if there's something to write,
430
* sowrite wouldn't have been called otherwise
431
*/
432
433
iov[0].iov_base = sb->sb_rptr;
434
iov[1].iov_base = NULL;
435
iov[1].iov_len = 0;
436
if (sb->sb_rptr < sb->sb_wptr) {
437
iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
438
/* Should never succeed, but... */
439
if (iov[0].iov_len > len)
440
iov[0].iov_len = len;
441
n = 1;
442
} else {
443
iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
444
if (iov[0].iov_len > len)
445
iov[0].iov_len = len;
446
len -= iov[0].iov_len;
447
if (len) {
448
iov[1].iov_base = sb->sb_data;
449
iov[1].iov_len = sb->sb_wptr - sb->sb_data;
450
if (iov[1].iov_len > len)
451
iov[1].iov_len = len;
452
n = 2;
453
} else
454
n = 1;
455
}
456
/* Check if there's urgent data to send, and if so, send it */
457
458
nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len, 0);
459
/* This should never happen, but people tell me it does *shrug* */
460
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
461
return 0;
462
463
if (nn <= 0) {
464
goto err_disconnected;
465
}
466
467
if (n == 2 && nn == iov[0].iov_len) {
468
int ret;
469
ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len, 0);
470
if (ret > 0)
471
nn += ret;
472
}
473
DEBUG_MISC(" ... wrote nn = %d bytes", nn);
474
475
/* Update sbuf */
476
sb->sb_cc -= nn;
477
sb->sb_rptr += nn;
478
if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
479
sb->sb_rptr -= sb->sb_datalen;
480
481
/*
482
* If in DRAIN mode, and there's no more data, set
483
* it CANTSENDMORE
484
*/
485
if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
486
sofcantsendmore(so);
487
488
return nn;
489
490
err_disconnected:
491
DEBUG_MISC(" --- sowrite disconnected, so->so_state = %x, errno = %d",
492
so->so_state, errno);
493
sofcantsendmore(so);
494
tcp_sockclosed(sototcpcb(so));
495
return -1;
496
}
497
498
/*
499
* recvfrom() a UDP socket
500
*/
501
void sorecvfrom(struct socket *so)
502
{
503
struct sockaddr_storage addr;
504
struct sockaddr_storage saddr, daddr;
505
socklen_t addrlen = sizeof(struct sockaddr_storage);
506
char buff[256];
507
508
#ifdef __linux__
509
ssize_t size;
510
struct msghdr msg;
511
struct iovec iov;
512
char control[1024];
513
514
/* First look for errors */
515
memset(&msg, 0, sizeof(msg));
516
msg.msg_name = &saddr;
517
msg.msg_namelen = sizeof(saddr);
518
msg.msg_control = control;
519
msg.msg_controllen = sizeof(control);
520
iov.iov_base = buff;
521
iov.iov_len = sizeof(buff);
522
msg.msg_iov = &iov;
523
msg.msg_iovlen = 1;
524
525
size = recvmsg(so->s, &msg, MSG_ERRQUEUE);
526
if (size >= 0) {
527
struct cmsghdr *cmsg;
528
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
529
530
if (cmsg->cmsg_level == IPPROTO_IP &&
531
cmsg->cmsg_type == IP_RECVERR) {
532
struct sock_extended_err *ee =
533
(struct sock_extended_err *) CMSG_DATA(cmsg);
534
535
if (ee->ee_origin == SO_EE_ORIGIN_ICMP) {
536
/* Got an ICMP error, forward it */
537
struct sockaddr_in *sin;
538
539
sin = (struct sockaddr_in *) SO_EE_OFFENDER(ee);
540
icmp_forward_error(so->so_m, ee->ee_type, ee->ee_code,
541
0, NULL, &sin->sin_addr);
542
}
543
}
544
else if (cmsg->cmsg_level == IPPROTO_IPV6 &&
545
cmsg->cmsg_type == IPV6_RECVERR) {
546
struct sock_extended_err *ee =
547
(struct sock_extended_err *) CMSG_DATA(cmsg);
548
549
if (ee->ee_origin == SO_EE_ORIGIN_ICMP6) {
550
/* Got an ICMPv6 error, forward it */
551
struct sockaddr_in6 *sin6;
552
553
sin6 = (struct sockaddr_in6 *) SO_EE_OFFENDER(ee);
554
icmp6_forward_error(so->so_m, ee->ee_type, ee->ee_code,
555
&sin6->sin6_addr);
556
}
557
}
558
}
559
return;
560
}
561
#endif
562
563
DEBUG_CALL("sorecvfrom");
564
DEBUG_ARG("so = %p", so);
565
566
if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
567
int len;
568
569
len = recvfrom(so->s, buff, 256, 0, (struct sockaddr *)&addr, &addrlen);
570
/* XXX Check if reply is "correct"? */
571
572
if (len == -1 || len == 0) {
573
uint8_t code = ICMP_UNREACH_PORT;
574
575
if (errno == EHOSTUNREACH)
576
code = ICMP_UNREACH_HOST;
577
else if (errno == ENETUNREACH)
578
code = ICMP_UNREACH_NET;
579
580
DEBUG_MISC(" udp icmp rx errno = %d-%s", errno, strerror(errno));
581
icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
582
} else {
583
icmp_reflect(so->so_m);
584
so->so_m = NULL; /* Don't m_free() it again! */
585
}
586
/* No need for this socket anymore, udp_detach it */
587
udp_detach(so);
588
} else if (so->so_type == IPPROTO_ICMPV6) { /* This is a "ping" reply */
589
int len;
590
591
len = recvfrom(so->s, buff, 256, 0, (struct sockaddr *)&addr, &addrlen);
592
/* XXX Check if reply is "correct"? */
593
594
if (len == -1 || len == 0) {
595
uint8_t code = ICMP6_UNREACH_PORT;
596
597
if (errno == EHOSTUNREACH)
598
code = ICMP6_UNREACH_ADDRESS;
599
else if (errno == ENETUNREACH)
600
code = ICMP6_UNREACH_NO_ROUTE;
601
602
DEBUG_MISC(" udp icmp6 rx errno = %d-%s", errno, strerror(errno));
603
icmp6_send_error(so->so_m, ICMP_UNREACH, code);
604
} else {
605
icmp6_reflect(so->so_m);
606
so->so_m = NULL; /* Don't m_free() it again! */
607
}
608
/* No need for this socket anymore, udp_detach it */
609
udp_detach(so);
610
} else { /* A "normal" UDP packet */
611
struct mbuf *m;
612
int len;
613
#ifdef _WIN32
614
unsigned long n;
615
#else
616
int n;
617
#endif
618
619
if (ioctlsocket(so->s, FIONREAD, &n) != 0) {
620
DEBUG_MISC(" ioctlsocket errno = %d-%s\n", errno, strerror(errno));
621
return;
622
}
623
624
m = m_get(so->slirp);
625
if (!m) {
626
return;
627
}
628
switch (so->so_ffamily) {
629
case AF_INET:
630
m->m_data += IF_MAXLINKHDR + sizeof(struct udpiphdr);
631
break;
632
case AF_INET6:
633
m->m_data +=
634
IF_MAXLINKHDR + sizeof(struct ip6) + sizeof(struct udphdr);
635
break;
636
default:
637
g_assert_not_reached();
638
}
639
640
/*
641
* XXX Shouldn't FIONREAD packets destined for port 53,
642
* but I don't know the max packet size for DNS lookups
643
*/
644
len = M_FREEROOM(m);
645
/* if (so->so_fport != htons(53)) { */
646
647
if (n > len) {
648
n = (m->m_data - m->m_dat) + m->m_len + n + 1;
649
m_inc(m, n);
650
len = M_FREEROOM(m);
651
}
652
/* } */
653
654
m->m_len = recvfrom(so->s, m->m_data, len, 0, (struct sockaddr *)&addr,
655
&addrlen);
656
DEBUG_MISC(" did recvfrom %d, errno = %d-%s", m->m_len, errno,
657
strerror(errno));
658
if (m->m_len < 0) {
659
if (errno == ENOTCONN) {
660
/*
661
* UDP socket got burnt, e.g. by suspend on iOS. Tear it down
662
* and let it get re-created if the guest still needs it
663
*/
664
udp_detach(so);
665
} else {
666
/* Report error as ICMP */
667
switch (so->so_lfamily) {
668
uint8_t code;
669
case AF_INET:
670
code = ICMP_UNREACH_PORT;
671
672
if (errno == EHOSTUNREACH) {
673
code = ICMP_UNREACH_HOST;
674
} else if (errno == ENETUNREACH) {
675
code = ICMP_UNREACH_NET;
676
}
677
678
DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code);
679
icmp_send_error(so->so_m, ICMP_UNREACH, code, 0,
680
strerror(errno));
681
break;
682
case AF_INET6:
683
code = ICMP6_UNREACH_PORT;
684
685
if (errno == EHOSTUNREACH) {
686
code = ICMP6_UNREACH_ADDRESS;
687
} else if (errno == ENETUNREACH) {
688
code = ICMP6_UNREACH_NO_ROUTE;
689
}
690
691
DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
692
icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
693
break;
694
default:
695
g_assert_not_reached();
696
}
697
m_free(m);
698
}
699
} else {
700
/*
701
* Hack: domain name lookup will be used the most for UDP,
702
* and since they'll only be used once there's no need
703
* for the 4 minute (or whatever) timeout... So we time them
704
* out much quicker (10 seconds for now...)
705
*/
706
if (so->so_expire) {
707
if (so->so_fport == htons(53))
708
so->so_expire = curtime + SO_EXPIREFAST;
709
else
710
so->so_expire = curtime + SO_EXPIRE;
711
}
712
713
/*
714
* If this packet was destined for CTL_ADDR,
715
* make it look like that's where it came from
716
*/
717
saddr = addr;
718
sotranslate_in(so, &saddr);
719
720
/* Perform lazy guest IP address resolution if needed. */
721
if (so->so_state & SS_HOSTFWD) {
722
if (soassign_guest_addr_if_needed(so) < 0) {
723
DEBUG_MISC(" guest address not available yet");
724
switch (so->so_lfamily) {
725
case AF_INET:
726
icmp_send_error(so->so_m, ICMP_UNREACH,
727
ICMP_UNREACH_HOST, 0,
728
"guest address not available yet");
729
break;
730
case AF_INET6:
731
icmp6_send_error(so->so_m, ICMP6_UNREACH,
732
ICMP6_UNREACH_ADDRESS);
733
break;
734
default:
735
g_assert_not_reached();
736
}
737
m_free(m);
738
return;
739
}
740
}
741
daddr = so->lhost.ss;
742
743
switch (so->so_ffamily) {
744
case AF_INET:
745
udp_output(so, m, (struct sockaddr_in *)&saddr,
746
(struct sockaddr_in *)&daddr, so->so_iptos);
747
break;
748
case AF_INET6:
749
udp6_output(so, m, (struct sockaddr_in6 *)&saddr,
750
(struct sockaddr_in6 *)&daddr);
751
break;
752
default:
753
g_assert_not_reached();
754
}
755
} /* rx error */
756
} /* if ping packet */
757
}
758
759
/*
760
* sendto() a socket
761
*/
762
int sosendto(struct socket *so, struct mbuf *m)
763
{
764
int ret;
765
struct sockaddr_storage addr;
766
767
DEBUG_CALL("sosendto");
768
DEBUG_ARG("so = %p", so);
769
DEBUG_ARG("m = %p", m);
770
771
addr = so->fhost.ss;
772
DEBUG_CALL(" sendto()ing)");
773
if (sotranslate_out(so, &addr) < 0) {
774
return -1;
775
}
776
777
/* Don't care what port we get */
778
ret = sendto(so->s, m->m_data, m->m_len, 0, (struct sockaddr *)&addr,
779
sockaddr_size(&addr));
780
if (ret < 0)
781
return -1;
782
783
/*
784
* Kill the socket if there's no reply in 4 minutes,
785
* but only if it's an expirable socket
786
*/
787
if (so->so_expire)
788
so->so_expire = curtime + SO_EXPIRE;
789
so->so_state &= SS_PERSISTENT_MASK;
790
so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
791
return 0;
792
}
793
794
struct socket *tcpx_listen(Slirp *slirp,
795
const struct sockaddr *haddr, socklen_t haddrlen,
796
const struct sockaddr *laddr, socklen_t laddrlen,
797
int flags)
798
{
799
struct socket *so;
800
int s, opt = 1;
801
socklen_t addrlen;
802
803
DEBUG_CALL("tcpx_listen");
804
/* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */
805
char addrstr[INET6_ADDRSTRLEN];
806
char portstr[6];
807
int ret;
808
switch (haddr->sa_family) {
809
case AF_INET:
810
case AF_INET6:
811
ret = getnameinfo(haddr, haddrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV);
812
g_assert(ret == 0);
813
DEBUG_ARG("hfamily = INET");
814
DEBUG_ARG("haddr = %s", addrstr);
815
DEBUG_ARG("hport = %s", portstr);
816
break;
817
#ifndef _WIN32
818
case AF_UNIX:
819
DEBUG_ARG("hfamily = UNIX");
820
DEBUG_ARG("hpath = %s", ((struct sockaddr_un *) haddr)->sun_path);
821
break;
822
#endif
823
default:
824
g_assert_not_reached();
825
}
826
switch (laddr->sa_family) {
827
case AF_INET:
828
case AF_INET6:
829
ret = getnameinfo(laddr, laddrlen, addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV);
830
g_assert(ret == 0);
831
DEBUG_ARG("laddr = %s", addrstr);
832
DEBUG_ARG("lport = %s", portstr);
833
break;
834
default:
835
g_assert_not_reached();
836
}
837
DEBUG_ARG("flags = %x", flags);
838
839
/*
840
* SS_HOSTFWD sockets can be accepted multiple times, so they can't be
841
* SS_FACCEPTONCE. Also, SS_HOSTFWD connections can be accepted and
842
* immediately closed if the guest address isn't available yet, which is
843
* incompatible with the "accept once" concept. Correct code will never
844
* request both, so disallow their combination by assertion.
845
*/
846
g_assert(!((flags & SS_HOSTFWD) && (flags & SS_FACCEPTONCE)));
847
848
so = socreate(slirp, IPPROTO_TCP);
849
850
/* Don't tcp_attach... we don't need so_snd nor so_rcv */
851
so->so_tcpcb = tcp_newtcpcb(so);
852
slirp_insque(so, &slirp->tcb);
853
854
/*
855
* SS_FACCEPTONCE sockets must time out.
856
*/
857
if (flags & SS_FACCEPTONCE)
858
so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT * 2;
859
860
so->so_state &= SS_PERSISTENT_MASK;
861
so->so_state |= (SS_FACCEPTCONN | flags);
862
863
sockaddr_copy(&so->lhost.sa, sizeof(so->lhost), laddr, laddrlen);
864
865
s = slirp_socket(haddr->sa_family, SOCK_STREAM, 0);
866
if ((s < 0) ||
867
(haddr->sa_family == AF_INET6 && slirp_socket_set_v6only(s, (flags & SS_HOSTFWD_V6ONLY) != 0) < 0) ||
868
(slirp_socket_set_fast_reuse(s) < 0) ||
869
(bind(s, haddr, haddrlen) < 0) ||
870
(listen(s, 1) < 0)) {
871
int tmperrno = errno; /* Don't clobber the real reason we failed */
872
if (s >= 0) {
873
closesocket(s);
874
}
875
sofree(so);
876
/* Restore the real errno */
877
#ifdef _WIN32
878
WSASetLastError(tmperrno);
879
#else
880
errno = tmperrno;
881
#endif
882
return NULL;
883
}
884
setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
885
slirp_socket_set_nodelay(s);
886
887
addrlen = sizeof(so->fhost);
888
getsockname(s, &so->fhost.sa, &addrlen);
889
sotranslate_accept(so);
890
891
so->s = s;
892
return so;
893
}
894
895
struct socket *tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport,
896
uint32_t laddr, unsigned lport, int flags)
897
{
898
struct sockaddr_in hsa, lsa;
899
900
memset(&hsa, 0, sizeof(hsa));
901
hsa.sin_family = AF_INET;
902
hsa.sin_addr.s_addr = haddr;
903
hsa.sin_port = hport;
904
905
memset(&lsa, 0, sizeof(lsa));
906
lsa.sin_family = AF_INET;
907
lsa.sin_addr.s_addr = laddr;
908
lsa.sin_port = lport;
909
910
return tcpx_listen(slirp, (const struct sockaddr *) &hsa, sizeof(hsa), (struct sockaddr *) &lsa, sizeof(lsa), flags);
911
}
912
913
/*
914
* Various session state calls
915
* XXX Should be #define's
916
* The socket state stuff needs work, these often get call 2 or 3
917
* times each when only 1 was needed
918
*/
919
void soisfconnecting(struct socket *so)
920
{
921
so->so_state &= ~(SS_NOFDREF | SS_ISFCONNECTED | SS_FCANTRCVMORE |
922
SS_FCANTSENDMORE | SS_FWDRAIN);
923
so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
924
}
925
926
void soisfconnected(struct socket *so)
927
{
928
so->so_state &= ~(SS_ISFCONNECTING | SS_FWDRAIN | SS_NOFDREF);
929
so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
930
}
931
932
static void sofcantrcvmore(struct socket *so)
933
{
934
if ((so->so_state & SS_NOFDREF) == 0) {
935
shutdown(so->s, 0);
936
}
937
so->so_state &= ~(SS_ISFCONNECTING);
938
if (so->so_state & SS_FCANTSENDMORE) {
939
so->so_state &= SS_PERSISTENT_MASK;
940
so->so_state |= SS_NOFDREF; /* Don't select it */
941
} else {
942
so->so_state |= SS_FCANTRCVMORE;
943
}
944
}
945
946
static void sofcantsendmore(struct socket *so)
947
{
948
if ((so->so_state & SS_NOFDREF) == 0) {
949
shutdown(so->s, 1); /* send FIN to fhost */
950
}
951
so->so_state &= ~(SS_ISFCONNECTING);
952
if (so->so_state & SS_FCANTRCVMORE) {
953
so->so_state &= SS_PERSISTENT_MASK;
954
so->so_state |= SS_NOFDREF; /* as above */
955
} else {
956
so->so_state |= SS_FCANTSENDMORE;
957
}
958
}
959
960
void sofwdrain(struct socket *so)
961
{
962
if (so->so_rcv.sb_cc)
963
so->so_state |= SS_FWDRAIN;
964
else
965
sofcantsendmore(so);
966
}
967
968
static bool sotranslate_out4(Slirp *s, struct socket *so, struct sockaddr_in *sin)
969
{
970
if (!s->disable_dns && so->so_faddr.s_addr == s->vnameserver_addr.s_addr) {
971
return so->so_fport == htons(53) && get_dns_addr(&sin->sin_addr) >= 0;
972
}
973
974
if (so->so_faddr.s_addr == s->vhost_addr.s_addr ||
975
so->so_faddr.s_addr == 0xffffffff) {
976
if (s->disable_host_loopback) {
977
return false;
978
}
979
980
sin->sin_addr = loopback_addr;
981
}
982
983
return true;
984
}
985
986
static bool sotranslate_out6(Slirp *s, struct socket *so, struct sockaddr_in6 *sin)
987
{
988
if (!s->disable_dns && in6_equal(&so->so_faddr6, &s->vnameserver_addr6)) {
989
uint32_t scope_id;
990
if (so->so_fport == htons(53) && get_dns6_addr(&sin->sin6_addr, &scope_id) >= 0) {
991
sin->sin6_scope_id = scope_id;
992
return true;
993
}
994
return false;
995
}
996
997
if (in6_equal_net(&so->so_faddr6, &s->vprefix_addr6, s->vprefix_len) ||
998
in6_equal(&so->so_faddr6, &(struct in6_addr)ALLNODES_MULTICAST)) {
999
if (s->disable_host_loopback) {
1000
return false;
1001
}
1002
1003
sin->sin6_addr = in6addr_loopback;
1004
}
1005
1006
return true;
1007
}
1008
1009
1010
int sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
1011
{
1012
bool ok = true;
1013
1014
switch (addr->ss_family) {
1015
case AF_INET:
1016
ok = sotranslate_out4(so->slirp, so, (struct sockaddr_in *)addr);
1017
break;
1018
case AF_INET6:
1019
ok = sotranslate_out6(so->slirp, so, (struct sockaddr_in6 *)addr);
1020
break;
1021
}
1022
1023
if (!ok) {
1024
errno = EPERM;
1025
return -1;
1026
}
1027
1028
return 0;
1029
}
1030
1031
void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
1032
{
1033
Slirp *slirp = so->slirp;
1034
struct sockaddr_in *sin = (struct sockaddr_in *)addr;
1035
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
1036
1037
switch (addr->ss_family) {
1038
case AF_INET:
1039
if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
1040
slirp->vnetwork_addr.s_addr) {
1041
uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
1042
1043
if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
1044
sin->sin_addr = slirp->vhost_addr;
1045
} else if (sin->sin_addr.s_addr == loopback_addr.s_addr ||
1046
so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
1047
sin->sin_addr = so->so_faddr;
1048
}
1049
}
1050
break;
1051
1052
case AF_INET6:
1053
if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
1054
slirp->vprefix_len)) {
1055
if (in6_equal(&sin6->sin6_addr, &in6addr_loopback) ||
1056
!in6_equal(&so->so_faddr6, &slirp->vhost_addr6)) {
1057
sin6->sin6_addr = so->so_faddr6;
1058
}
1059
}
1060
break;
1061
1062
default:
1063
break;
1064
}
1065
}
1066
1067
void sotranslate_accept(struct socket *so)
1068
{
1069
Slirp *slirp = so->slirp;
1070
1071
switch (so->so_ffamily) {
1072
case AF_INET:
1073
if (so->so_faddr.s_addr == INADDR_ANY ||
1074
(so->so_faddr.s_addr & loopback_mask) ==
1075
(loopback_addr.s_addr & loopback_mask)) {
1076
so->so_faddr = slirp->vhost_addr;
1077
}
1078
break;
1079
1080
case AF_INET6:
1081
if (in6_equal(&so->so_faddr6, &in6addr_any) ||
1082
in6_equal(&so->so_faddr6, &in6addr_loopback)) {
1083
so->so_faddr6 = slirp->vhost_addr6;
1084
}
1085
break;
1086
1087
case AF_UNIX: {
1088
/* Translate Unix socket to random ephemeral source port. We obtain
1089
* this source port by binding to port 0 so that the OS allocates a
1090
* port for us. If this fails, we fall back to choosing a random port
1091
* with a random number generator. */
1092
int s;
1093
struct sockaddr_in in_addr;
1094
struct sockaddr_in6 in6_addr;
1095
socklen_t in_addr_len;
1096
1097
if (so->slirp->in_enabled) {
1098
so->so_ffamily = AF_INET;
1099
so->so_faddr = slirp->vhost_addr;
1100
so->so_fport = 0;
1101
1102
switch (so->so_type) {
1103
case IPPROTO_TCP:
1104
s = slirp_socket(PF_INET, SOCK_STREAM, 0);
1105
break;
1106
case IPPROTO_UDP:
1107
s = slirp_socket(PF_INET, SOCK_DGRAM, 0);
1108
break;
1109
default:
1110
g_assert_not_reached();
1111
break;
1112
}
1113
if (s < 0) {
1114
g_error("Ephemeral slirp_socket() allocation failed");
1115
goto unix2inet_cont;
1116
}
1117
memset(&in_addr, 0, sizeof(in_addr));
1118
in_addr.sin_family = AF_INET;
1119
in_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1120
in_addr.sin_port = htons(0);
1121
if (bind(s, (struct sockaddr *) &in_addr, sizeof(in_addr))) {
1122
g_error("Ephemeral bind() failed");
1123
closesocket(s);
1124
goto unix2inet_cont;
1125
}
1126
in_addr_len = sizeof(in_addr);
1127
if (getsockname(s, (struct sockaddr *) &in_addr, &in_addr_len)) {
1128
g_error("Ephemeral getsockname() failed");
1129
closesocket(s);
1130
goto unix2inet_cont;
1131
}
1132
so->s_aux = s;
1133
so->so_fport = in_addr.sin_port;
1134
1135
unix2inet_cont:
1136
if (!so->so_fport) {
1137
g_warning("Falling back to random port allocation");
1138
so->so_fport = htons(g_rand_int_range(slirp->grand, 49152, 65536));
1139
}
1140
} else if (so->slirp->in6_enabled) {
1141
so->so_ffamily = AF_INET6;
1142
so->so_faddr6 = slirp->vhost_addr6;
1143
so->so_fport6 = 0;
1144
1145
switch (so->so_type) {
1146
case IPPROTO_TCP:
1147
s = slirp_socket(PF_INET6, SOCK_STREAM, 0);
1148
break;
1149
case IPPROTO_UDP:
1150
s = slirp_socket(PF_INET6, SOCK_DGRAM, 0);
1151
break;
1152
default:
1153
g_assert_not_reached();
1154
break;
1155
}
1156
if (s < 0) {
1157
g_error("Ephemeral slirp_socket() allocation failed");
1158
goto unix2inet6_cont;
1159
}
1160
memset(&in6_addr, 0, sizeof(in6_addr));
1161
in6_addr.sin6_family = AF_INET6;
1162
in6_addr.sin6_addr = in6addr_loopback;
1163
in6_addr.sin6_port = htons(0);
1164
if (bind(s, (struct sockaddr *) &in6_addr, sizeof(in6_addr))) {
1165
g_error("Ephemeral bind() failed");
1166
closesocket(s);
1167
goto unix2inet6_cont;
1168
}
1169
in_addr_len = sizeof(in6_addr);
1170
if (getsockname(s, (struct sockaddr *) &in6_addr, &in_addr_len)) {
1171
g_error("Ephemeral getsockname() failed");
1172
closesocket(s);
1173
goto unix2inet6_cont;
1174
}
1175
so->s_aux = s;
1176
so->so_fport6 = in6_addr.sin6_port;
1177
1178
unix2inet6_cont:
1179
if (!so->so_fport6) {
1180
g_warning("Falling back to random port allocation");
1181
so->so_fport6 = htons(g_rand_int_range(slirp->grand, 49152, 65536));
1182
}
1183
} else {
1184
g_assert_not_reached();
1185
}
1186
break;
1187
} /* case AF_UNIX */
1188
1189
default:
1190
break;
1191
}
1192
}
1193
1194
void sodrop(struct socket *s, int num)
1195
{
1196
if (sbdrop(&s->so_snd, num)) {
1197
s->slirp->cb->notify(s->slirp->opaque);
1198
}
1199
}
1200
1201
/*
1202
* Translate "addr-any" in so->lhost to the guest's actual address.
1203
* Returns 0 for success, or -1 if the guest doesn't have an address yet
1204
* with errno set to EHOSTUNREACH.
1205
*
1206
* The guest address is taken from the first entry in the ARP table for IPv4
1207
* and the first entry in the NDP table for IPv6.
1208
* Note: The IPv4 path isn't exercised yet as all hostfwd "" guest translations
1209
* are handled immediately by using slirp->vdhcp_startaddr.
1210
*/
1211
int soassign_guest_addr_if_needed(struct socket *so)
1212
{
1213
Slirp *slirp = so->slirp;
1214
/* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */
1215
char addrstr[INET6_ADDRSTRLEN];
1216
char portstr[6];
1217
1218
g_assert(so->so_state & SS_HOSTFWD);
1219
1220
switch (so->so_ffamily) {
1221
case AF_INET:
1222
if (so->so_laddr.s_addr == INADDR_ANY) {
1223
g_assert_not_reached();
1224
}
1225
break;
1226
1227
case AF_INET6:
1228
if (in6_zero(&so->so_laddr6)) {
1229
int ret;
1230
if (in6_zero(&slirp->ndp_table.guest_in6_addr)) {
1231
errno = EHOSTUNREACH;
1232
return -1;
1233
}
1234
so->so_laddr6 = slirp->ndp_table.guest_in6_addr;
1235
ret = getnameinfo((const struct sockaddr *) &so->lhost.ss,
1236
sizeof(so->lhost.ss), addrstr, sizeof(addrstr),
1237
portstr, sizeof(portstr),
1238
NI_NUMERICHOST|NI_NUMERICSERV);
1239
g_assert(ret == 0);
1240
DEBUG_MISC("%s: new ip = [%s]:%s", __func__, addrstr, portstr);
1241
}
1242
break;
1243
1244
default:
1245
break;
1246
}
1247
1248
return 0;
1249
}
1250
1251