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