|
|
1.1 root 1: /*
2: * Copyright (c) 1995 Danny Gasparovski.
1.1.1.3 root 3: *
4: * Please read the file COPYRIGHT for the
1.1 root 5: * terms and conditions of the copyright.
6: */
7:
1.1.1.4 root 8: #include "qemu-common.h"
1.1 root 9: #include <slirp.h>
10: #include "ip_icmp.h"
1.1.1.2 root 11: #ifdef __sun__
12: #include <sys/filio.h>
13: #endif
1.1 root 14:
1.1.1.3 root 15: static void sofcantrcvmore(struct socket *so);
16: static void sofcantsendmore(struct socket *so);
17:
1.1 root 18: struct socket *
1.1.1.5 root 19: solookup(struct socket *head, struct in_addr laddr, u_int lport,
20: struct in_addr faddr, u_int fport)
1.1 root 21: {
22: struct socket *so;
1.1.1.3 root 23:
1.1 root 24: for (so = head->so_next; so != head; so = so->so_next) {
1.1.1.3 root 25: if (so->so_lport == lport &&
1.1 root 26: so->so_laddr.s_addr == laddr.s_addr &&
27: so->so_faddr.s_addr == faddr.s_addr &&
28: so->so_fport == fport)
29: break;
30: }
1.1.1.3 root 31:
1.1 root 32: if (so == head)
33: return (struct socket *)NULL;
34: return so;
1.1.1.3 root 35:
1.1 root 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: */
43: struct socket *
1.1.1.5 root 44: socreate(Slirp *slirp)
1.1 root 45: {
46: struct socket *so;
1.1.1.3 root 47:
1.1 root 48: so = (struct socket *)malloc(sizeof(struct socket));
49: if(so) {
50: memset(so, 0, sizeof(struct socket));
51: so->so_state = SS_NOFDREF;
52: so->s = -1;
1.1.1.5 root 53: so->slirp = slirp;
1.1 root 54: }
55: return(so);
56: }
57:
58: /*
59: * remque and free a socket, clobber cache
60: */
61: void
1.1.1.5 root 62: sofree(struct socket *so)
1.1 root 63: {
1.1.1.5 root 64: Slirp *slirp = so->slirp;
65:
1.1 root 66: if (so->so_emu==EMU_RSH && so->extra) {
67: sofree(so->extra);
68: so->extra=NULL;
69: }
1.1.1.5 root 70: if (so == slirp->tcp_last_so) {
71: slirp->tcp_last_so = &slirp->tcb;
72: } else if (so == slirp->udp_last_so) {
73: slirp->udp_last_so = &slirp->udb;
74: }
1.1 root 75: m_free(so->so_m);
1.1.1.3 root 76:
77: if(so->so_next && so->so_prev)
1.1 root 78: remque(so); /* crashes if so is not in a queue */
79:
80: free(so);
81: }
82:
1.1.1.4 root 83: size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
1.1 root 84: {
1.1.1.4 root 85: int n, lss, total;
1.1 root 86: struct sbuf *sb = &so->so_snd;
87: int len = sb->sb_datalen - sb->sb_cc;
88: int mss = so->so_tcpcb->t_maxseg;
1.1.1.3 root 89:
1.1.1.4 root 90: DEBUG_CALL("sopreprbuf");
1.1 root 91: DEBUG_ARG("so = %lx", (long )so);
1.1.1.3 root 92:
1.1.1.4 root 93: if (len <= 0)
94: return 0;
95:
1.1 root 96: iov[0].iov_base = sb->sb_wptr;
1.1.1.4 root 97: iov[1].iov_base = NULL;
98: iov[1].iov_len = 0;
1.1 root 99: if (sb->sb_wptr < sb->sb_rptr) {
100: iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
101: /* Should never succeed, but... */
102: if (iov[0].iov_len > len)
103: iov[0].iov_len = len;
104: if (iov[0].iov_len > mss)
105: iov[0].iov_len -= iov[0].iov_len%mss;
106: n = 1;
107: } else {
108: iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
109: /* Should never succeed, but... */
110: if (iov[0].iov_len > len) iov[0].iov_len = len;
111: len -= iov[0].iov_len;
112: if (len) {
113: iov[1].iov_base = sb->sb_data;
114: iov[1].iov_len = sb->sb_rptr - sb->sb_data;
115: if(iov[1].iov_len > len)
116: iov[1].iov_len = len;
117: total = iov[0].iov_len + iov[1].iov_len;
118: if (total > mss) {
119: lss = total%mss;
120: if (iov[1].iov_len > lss) {
121: iov[1].iov_len -= lss;
122: n = 2;
123: } else {
124: lss -= iov[1].iov_len;
125: iov[0].iov_len -= lss;
126: n = 1;
127: }
128: } else
129: n = 2;
130: } else {
131: if (iov[0].iov_len > mss)
132: iov[0].iov_len -= iov[0].iov_len%mss;
133: n = 1;
134: }
135: }
1.1.1.4 root 136: if (np)
137: *np = n;
138:
139: return iov[0].iov_len + (n - 1) * iov[1].iov_len;
140: }
141:
142: /*
143: * Read from so's socket into sb_snd, updating all relevant sbuf fields
144: * NOTE: This will only be called if it is select()ed for reading, so
145: * a read() of 0 (or less) means it's disconnected
146: */
147: int
1.1.1.5 root 148: soread(struct socket *so)
1.1.1.4 root 149: {
150: int n, nn;
151: struct sbuf *sb = &so->so_snd;
152: struct iovec iov[2];
153:
154: DEBUG_CALL("soread");
155: DEBUG_ARG("so = %lx", (long )so);
156:
157: /*
158: * No need to check if there's enough room to read.
159: * soread wouldn't have been called if there weren't
160: */
161: sopreprbuf(so, iov, &n);
1.1.1.3 root 162:
1.1 root 163: #ifdef HAVE_READV
164: nn = readv(so->s, (struct iovec *)iov, n);
165: DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
166: #else
167: nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
1.1.1.3 root 168: #endif
1.1 root 169: if (nn <= 0) {
170: if (nn < 0 && (errno == EINTR || errno == EAGAIN))
171: return 0;
172: else {
173: DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
174: sofcantrcvmore(so);
175: tcp_sockclosed(sototcpcb(so));
176: return -1;
177: }
178: }
1.1.1.3 root 179:
1.1 root 180: #ifndef HAVE_READV
181: /*
182: * If there was no error, try and read the second time round
183: * We read again if n = 2 (ie, there's another part of the buffer)
184: * and we read as much as we could in the first read
185: * We don't test for <= 0 this time, because there legitimately
186: * might not be any more data (since the socket is non-blocking),
187: * a close will be detected on next iteration.
188: * A return of -1 wont (shouldn't) happen, since it didn't happen above
189: */
190: if (n == 2 && nn == iov[0].iov_len) {
191: int ret;
192: ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
193: if (ret > 0)
194: nn += ret;
195: }
1.1.1.3 root 196:
1.1 root 197: DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
198: #endif
1.1.1.3 root 199:
1.1 root 200: /* Update fields */
201: sb->sb_cc += nn;
202: sb->sb_wptr += nn;
203: if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
204: sb->sb_wptr -= sb->sb_datalen;
205: return nn;
206: }
1.1.1.3 root 207:
1.1.1.4 root 208: int soreadbuf(struct socket *so, const char *buf, int size)
209: {
210: int n, nn, copy = size;
211: struct sbuf *sb = &so->so_snd;
212: struct iovec iov[2];
213:
214: DEBUG_CALL("soreadbuf");
215: DEBUG_ARG("so = %lx", (long )so);
216:
217: /*
218: * No need to check if there's enough room to read.
219: * soread wouldn't have been called if there weren't
220: */
221: if (sopreprbuf(so, iov, &n) < size)
222: goto err;
223:
224: nn = MIN(iov[0].iov_len, copy);
225: memcpy(iov[0].iov_base, buf, nn);
226:
227: copy -= nn;
228: buf += nn;
229:
230: if (copy == 0)
231: goto done;
232:
233: memcpy(iov[1].iov_base, buf, copy);
234:
235: done:
236: /* Update fields */
237: sb->sb_cc += size;
238: sb->sb_wptr += size;
239: if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
240: sb->sb_wptr -= sb->sb_datalen;
241: return size;
242: err:
243:
244: sofcantrcvmore(so);
245: tcp_sockclosed(sototcpcb(so));
246: fprintf(stderr, "soreadbuf buffer to small");
247: return -1;
248: }
249:
1.1 root 250: /*
251: * Get urgent data
1.1.1.3 root 252: *
1.1 root 253: * When the socket is created, we set it SO_OOBINLINE,
254: * so when OOB data arrives, we soread() it and everything
255: * in the send buffer is sent as urgent data
256: */
257: void
1.1.1.5 root 258: sorecvoob(struct socket *so)
1.1 root 259: {
260: struct tcpcb *tp = sototcpcb(so);
261:
262: DEBUG_CALL("sorecvoob");
263: DEBUG_ARG("so = %lx", (long)so);
1.1.1.3 root 264:
1.1 root 265: /*
266: * We take a guess at how much urgent data has arrived.
267: * In most situations, when urgent data arrives, the next
268: * read() should get all the urgent data. This guess will
269: * be wrong however if more data arrives just after the
1.1.1.3 root 270: * urgent data, or the read() doesn't return all the
1.1 root 271: * urgent data.
272: */
273: soread(so);
274: tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
275: tp->t_force = 1;
276: tcp_output(tp);
277: tp->t_force = 0;
278: }
279:
280: /*
281: * Send urgent data
282: * There's a lot duplicated code here, but...
283: */
284: int
1.1.1.5 root 285: sosendoob(struct socket *so)
1.1 root 286: {
287: struct sbuf *sb = &so->so_rcv;
288: char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
1.1.1.3 root 289:
1.1 root 290: int n, len;
1.1.1.3 root 291:
1.1 root 292: DEBUG_CALL("sosendoob");
293: DEBUG_ARG("so = %lx", (long)so);
294: DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
1.1.1.3 root 295:
1.1 root 296: if (so->so_urgc > 2048)
297: so->so_urgc = 2048; /* XXXX */
1.1.1.3 root 298:
1.1 root 299: if (sb->sb_rptr < sb->sb_wptr) {
300: /* We can send it directly */
1.1.1.4 root 301: n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
1.1 root 302: so->so_urgc -= n;
1.1.1.3 root 303:
1.1 root 304: DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
305: } else {
1.1.1.3 root 306: /*
1.1 root 307: * Since there's no sendv or sendtov like writev,
308: * we must copy all data to a linear buffer then
309: * send it all
310: */
311: len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
312: if (len > so->so_urgc) len = so->so_urgc;
313: memcpy(buff, sb->sb_rptr, len);
314: so->so_urgc -= len;
315: if (so->so_urgc) {
316: n = sb->sb_wptr - sb->sb_data;
317: if (n > so->so_urgc) n = so->so_urgc;
318: memcpy((buff + len), sb->sb_data, n);
319: so->so_urgc -= n;
320: len += n;
321: }
1.1.1.4 root 322: n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
1.1 root 323: #ifdef DEBUG
324: if (n != len)
325: DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
1.1.1.3 root 326: #endif
1.1 root 327: DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
328: }
1.1.1.3 root 329:
1.1 root 330: sb->sb_cc -= n;
331: sb->sb_rptr += n;
332: if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
333: sb->sb_rptr -= sb->sb_datalen;
1.1.1.3 root 334:
1.1 root 335: return n;
336: }
337:
338: /*
1.1.1.3 root 339: * Write data from so_rcv to so's socket,
1.1 root 340: * updating all sbuf field as necessary
341: */
342: int
1.1.1.5 root 343: sowrite(struct socket *so)
1.1 root 344: {
345: int n,nn;
346: struct sbuf *sb = &so->so_rcv;
347: int len = sb->sb_cc;
348: struct iovec iov[2];
1.1.1.3 root 349:
1.1 root 350: DEBUG_CALL("sowrite");
351: DEBUG_ARG("so = %lx", (long)so);
1.1.1.3 root 352:
1.1 root 353: if (so->so_urgc) {
354: sosendoob(so);
355: if (sb->sb_cc == 0)
356: return 0;
357: }
358:
359: /*
360: * No need to check if there's something to write,
361: * sowrite wouldn't have been called otherwise
362: */
1.1.1.3 root 363:
1.1 root 364: iov[0].iov_base = sb->sb_rptr;
1.1.1.4 root 365: iov[1].iov_base = NULL;
366: iov[1].iov_len = 0;
1.1 root 367: if (sb->sb_rptr < sb->sb_wptr) {
368: iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
369: /* Should never succeed, but... */
370: if (iov[0].iov_len > len) iov[0].iov_len = len;
371: n = 1;
372: } else {
373: iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
374: if (iov[0].iov_len > len) iov[0].iov_len = len;
375: len -= iov[0].iov_len;
376: if (len) {
377: iov[1].iov_base = sb->sb_data;
378: iov[1].iov_len = sb->sb_wptr - sb->sb_data;
379: if (iov[1].iov_len > len) iov[1].iov_len = len;
380: n = 2;
381: } else
382: n = 1;
383: }
384: /* Check if there's urgent data to send, and if so, send it */
385:
386: #ifdef HAVE_READV
387: nn = writev(so->s, (const struct iovec *)iov, n);
1.1.1.3 root 388:
1.1 root 389: DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
390: #else
1.1.1.4 root 391: nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
1.1 root 392: #endif
393: /* This should never happen, but people tell me it does *shrug* */
394: if (nn < 0 && (errno == EAGAIN || errno == EINTR))
395: return 0;
1.1.1.3 root 396:
1.1 root 397: if (nn <= 0) {
398: DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
399: so->so_state, errno));
400: sofcantsendmore(so);
401: tcp_sockclosed(sototcpcb(so));
402: return -1;
403: }
1.1.1.3 root 404:
1.1 root 405: #ifndef HAVE_READV
406: if (n == 2 && nn == iov[0].iov_len) {
407: int ret;
1.1.1.4 root 408: ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
1.1 root 409: if (ret > 0)
410: nn += ret;
411: }
412: DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn));
413: #endif
1.1.1.3 root 414:
1.1 root 415: /* Update sbuf */
416: sb->sb_cc -= nn;
417: sb->sb_rptr += nn;
418: if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
419: sb->sb_rptr -= sb->sb_datalen;
1.1.1.3 root 420:
1.1 root 421: /*
422: * If in DRAIN mode, and there's no more data, set
423: * it CANTSENDMORE
424: */
425: if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
426: sofcantsendmore(so);
1.1.1.3 root 427:
1.1 root 428: return nn;
429: }
430:
431: /*
432: * recvfrom() a UDP socket
433: */
434: void
1.1.1.5 root 435: sorecvfrom(struct socket *so)
1.1 root 436: {
437: struct sockaddr_in addr;
1.1.1.4 root 438: socklen_t addrlen = sizeof(struct sockaddr_in);
1.1.1.3 root 439:
1.1 root 440: DEBUG_CALL("sorecvfrom");
441: DEBUG_ARG("so = %lx", (long)so);
1.1.1.3 root 442:
1.1 root 443: if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */
444: char buff[256];
445: int len;
1.1.1.3 root 446:
447: len = recvfrom(so->s, buff, 256, 0,
1.1 root 448: (struct sockaddr *)&addr, &addrlen);
449: /* XXX Check if reply is "correct"? */
1.1.1.3 root 450:
1.1 root 451: if(len == -1 || len == 0) {
452: u_char code=ICMP_UNREACH_PORT;
453:
454: if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
455: else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
1.1.1.3 root 456:
1.1 root 457: DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
458: errno,strerror(errno)));
459: icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
460: } else {
461: icmp_reflect(so->so_m);
1.1.1.5 root 462: so->so_m = NULL; /* Don't m_free() it again! */
1.1 root 463: }
464: /* No need for this socket anymore, udp_detach it */
465: udp_detach(so);
466: } else { /* A "normal" UDP packet */
467: struct mbuf *m;
1.1.1.5 root 468: int len;
469: #ifdef _WIN32
470: unsigned long n;
471: #else
472: int n;
473: #endif
1.1 root 474:
1.1.1.5 root 475: m = m_get(so->slirp);
476: if (!m) {
477: return;
478: }
1.1.1.3 root 479: m->m_data += IF_MAXLINKHDR;
480:
481: /*
1.1 root 482: * XXX Shouldn't FIONREAD packets destined for port 53,
483: * but I don't know the max packet size for DNS lookups
484: */
485: len = M_FREEROOM(m);
486: /* if (so->so_fport != htons(53)) { */
487: ioctlsocket(so->s, FIONREAD, &n);
1.1.1.3 root 488:
1.1 root 489: if (n > len) {
490: n = (m->m_data - m->m_dat) + m->m_len + n + 1;
491: m_inc(m, n);
492: len = M_FREEROOM(m);
493: }
494: /* } */
1.1.1.3 root 495:
1.1 root 496: m->m_len = recvfrom(so->s, m->m_data, len, 0,
497: (struct sockaddr *)&addr, &addrlen);
1.1.1.3 root 498: DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
1.1 root 499: m->m_len, errno,strerror(errno)));
500: if(m->m_len<0) {
501: u_char code=ICMP_UNREACH_PORT;
502:
503: if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
504: else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
1.1.1.3 root 505:
1.1 root 506: DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
507: icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
508: m_free(m);
509: } else {
510: /*
511: * Hack: domain name lookup will be used the most for UDP,
512: * and since they'll only be used once there's no need
513: * for the 4 minute (or whatever) timeout... So we time them
514: * out much quicker (10 seconds for now...)
515: */
516: if (so->so_expire) {
517: if (so->so_fport == htons(53))
518: so->so_expire = curtime + SO_EXPIREFAST;
519: else
520: so->so_expire = curtime + SO_EXPIRE;
521: }
522:
1.1.1.3 root 523: /*
1.1 root 524: * If this packet was destined for CTL_ADDR,
525: * make it look like that's where it came from, done by udp_output
526: */
527: udp_output(so, m, &addr);
528: } /* rx error */
529: } /* if ping packet */
530: }
531:
532: /*
533: * sendto() a socket
534: */
535: int
1.1.1.5 root 536: sosendto(struct socket *so, struct mbuf *m)
1.1 root 537: {
1.1.1.5 root 538: Slirp *slirp = so->slirp;
1.1 root 539: int ret;
540: struct sockaddr_in addr;
541:
542: DEBUG_CALL("sosendto");
543: DEBUG_ARG("so = %lx", (long)so);
544: DEBUG_ARG("m = %lx", (long)m);
1.1.1.3 root 545:
1.1 root 546: addr.sin_family = AF_INET;
1.1.1.5 root 547: if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
548: slirp->vnetwork_addr.s_addr) {
1.1 root 549: /* It's an alias */
1.1.1.5 root 550: if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
1.1.1.6 root 551: if (get_dns_addr(&addr.sin_addr) < 0)
552: addr.sin_addr = loopback_addr;
1.1.1.5 root 553: } else {
1.1 root 554: addr.sin_addr = loopback_addr;
555: }
556: } else
557: addr.sin_addr = so->so_faddr;
558: addr.sin_port = so->so_fport;
559:
560: DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
1.1.1.3 root 561:
1.1 root 562: /* Don't care what port we get */
563: ret = sendto(so->s, m->m_data, m->m_len, 0,
564: (struct sockaddr *)&addr, sizeof (struct sockaddr));
565: if (ret < 0)
566: return -1;
1.1.1.3 root 567:
1.1 root 568: /*
569: * Kill the socket if there's no reply in 4 minutes,
570: * but only if it's an expirable socket
571: */
572: if (so->so_expire)
573: so->so_expire = curtime + SO_EXPIRE;
1.1.1.5 root 574: so->so_state &= SS_PERSISTENT_MASK;
575: so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
1.1 root 576: return 0;
577: }
578:
579: /*
1.1.1.5 root 580: * Listen for incoming TCP connections
1.1 root 581: */
582: struct socket *
1.1.1.7 ! root 583: tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
1.1.1.5 root 584: u_int lport, int flags)
1.1 root 585: {
586: struct sockaddr_in addr;
587: struct socket *so;
1.1.1.4 root 588: int s, opt = 1;
589: socklen_t addrlen = sizeof(addr);
1.1.1.7 ! root 590: memset(&addr, 0, addrlen);
1.1 root 591:
1.1.1.5 root 592: DEBUG_CALL("tcp_listen");
593: DEBUG_ARG("haddr = %x", haddr);
594: DEBUG_ARG("hport = %d", hport);
1.1 root 595: DEBUG_ARG("laddr = %x", laddr);
596: DEBUG_ARG("lport = %d", lport);
597: DEBUG_ARG("flags = %x", flags);
1.1.1.3 root 598:
1.1.1.5 root 599: so = socreate(slirp);
600: if (!so) {
1.1 root 601: return NULL;
602: }
1.1.1.3 root 603:
1.1 root 604: /* Don't tcp_attach... we don't need so_snd nor so_rcv */
605: if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
606: free(so);
607: return NULL;
608: }
1.1.1.5 root 609: insque(so, &slirp->tcb);
1.1.1.3 root 610:
611: /*
1.1 root 612: * SS_FACCEPTONCE sockets must time out.
613: */
614: if (flags & SS_FACCEPTONCE)
615: so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
1.1.1.3 root 616:
1.1.1.5 root 617: so->so_state &= SS_PERSISTENT_MASK;
618: so->so_state |= (SS_FACCEPTCONN | flags);
1.1 root 619: so->so_lport = lport; /* Kept in network format */
620: so->so_laddr.s_addr = laddr; /* Ditto */
1.1.1.3 root 621:
1.1 root 622: addr.sin_family = AF_INET;
1.1.1.5 root 623: addr.sin_addr.s_addr = haddr;
624: addr.sin_port = hport;
1.1.1.3 root 625:
1.1.1.6 root 626: if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
1.1.1.2 root 627: (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
1.1 root 628: (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
629: (listen(s,1) < 0)) {
630: int tmperrno = errno; /* Don't clobber the real reason we failed */
1.1.1.3 root 631:
1.1 root 632: close(s);
633: sofree(so);
634: /* Restore the real errno */
635: #ifdef _WIN32
636: WSASetLastError(tmperrno);
637: #else
638: errno = tmperrno;
639: #endif
640: return NULL;
641: }
642: setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
1.1.1.3 root 643:
1.1 root 644: getsockname(s,(struct sockaddr *)&addr,&addrlen);
645: so->so_fport = addr.sin_port;
646: if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
1.1.1.5 root 647: so->so_faddr = slirp->vhost_addr;
1.1 root 648: else
649: so->so_faddr = addr.sin_addr;
650:
651: so->s = s;
652: return so;
653: }
654:
655: /*
656: * Various session state calls
657: * XXX Should be #define's
658: * The socket state stuff needs work, these often get call 2 or 3
659: * times each when only 1 was needed
660: */
661: void
1.1.1.5 root 662: soisfconnecting(struct socket *so)
1.1 root 663: {
664: so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
665: SS_FCANTSENDMORE|SS_FWDRAIN);
666: so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
667: }
668:
669: void
1.1.1.5 root 670: soisfconnected(struct socket *so)
1.1 root 671: {
672: so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
673: so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
674: }
675:
1.1.1.3 root 676: static void
677: sofcantrcvmore(struct socket *so)
1.1 root 678: {
679: if ((so->so_state & SS_NOFDREF) == 0) {
680: shutdown(so->s,0);
681: if(global_writefds) {
682: FD_CLR(so->s,global_writefds);
683: }
684: }
685: so->so_state &= ~(SS_ISFCONNECTING);
1.1.1.5 root 686: if (so->so_state & SS_FCANTSENDMORE) {
687: so->so_state &= SS_PERSISTENT_MASK;
688: so->so_state |= SS_NOFDREF; /* Don't select it */
689: } else {
1.1 root 690: so->so_state |= SS_FCANTRCVMORE;
1.1.1.5 root 691: }
1.1 root 692: }
693:
1.1.1.3 root 694: static void
695: sofcantsendmore(struct socket *so)
1.1 root 696: {
697: if ((so->so_state & SS_NOFDREF) == 0) {
698: shutdown(so->s,1); /* send FIN to fhost */
699: if (global_readfds) {
700: FD_CLR(so->s,global_readfds);
701: }
702: if (global_xfds) {
703: FD_CLR(so->s,global_xfds);
704: }
705: }
706: so->so_state &= ~(SS_ISFCONNECTING);
1.1.1.5 root 707: if (so->so_state & SS_FCANTRCVMORE) {
708: so->so_state &= SS_PERSISTENT_MASK;
709: so->so_state |= SS_NOFDREF; /* as above */
710: } else {
1.1 root 711: so->so_state |= SS_FCANTSENDMORE;
1.1.1.5 root 712: }
1.1 root 713: }
714:
715: /*
716: * Set write drain mode
717: * Set CANTSENDMORE once all data has been write()n
718: */
719: void
1.1.1.5 root 720: sofwdrain(struct socket *so)
1.1 root 721: {
722: if (so->so_rcv.sb_cc)
723: so->so_state |= SS_FWDRAIN;
724: else
725: sofcantsendmore(so);
726: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.