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