Changeset 52798 in vbox
- Timestamp:
- Sep 21, 2014 9:19:38 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 96193
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/slirp.c
r52792 r52798 1011 1011 if (sockerr != 0) 1012 1012 { 1013 /* "continue" tcp_input() to reject connection from guest */ 1014 so->so_state = SS_NOFDREF; 1015 TCP_INPUT(pData, NULL, 0, so); 1013 tcp_fconnect_failed(pData, so, sockerr); 1016 1014 ret = slirpVerifyAndFreeSocket(pData, so); 1017 1015 Assert(ret == 1); /* freed */ -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r51137 r52798 321 321 int tcp_reass (PNATState, struct tcpcb *, struct tcphdr *, int *, struct mbuf *); 322 322 void tcp_input (PNATState, register struct mbuf *, int, struct socket *); 323 void tcp_fconnect_failed(PNATState, struct socket *, int); 323 324 void tcp_dooptions (PNATState, struct tcpcb *, u_char *, int, struct tcpiphdr *); 324 325 void tcp_xmit_timer (PNATState, register struct tcpcb *, int); -
trunk/src/VBox/Devices/Network/slirp/socket.c
r52712 r52798 214 214 m_freem(pData, so->so_m); 215 215 so->so_m = NULL; 216 } 217 218 if (so->so_ohdr != NULL) 219 { 220 RTMemFree(so->so_ohdr); 221 so->so_ohdr = NULL; 216 222 } 217 223 -
trunk/src/VBox/Devices/Network/slirp/socket.h
r52755 r52798 59 59 struct tcpiphdr *so_ti; /* Pointer to the original ti within 60 60 * so_mconn, for non-blocking connections */ 61 uint8_t *so_ohdr; /* unmolested IP header of the datagram in so_m */ 61 62 int so_urgc; 62 63 struct in_addr so_faddr; /* foreign host table entry */ -
trunk/src/VBox/Devices/Network/slirp/tcp_input.c
r51727 r52798 290 290 tcp_input(PNATState pData, register struct mbuf *m, int iphlen, struct socket *inso) 291 291 { 292 struct ip save_ip, *ip;292 struct ip *ip, *save_ip; 293 293 register struct tcpiphdr *ti; 294 294 caddr_t optp = NULL; … … 303 303 u_long tiwin; 304 304 /* int ts_present = 0; */ 305 size_t ohdrlen; 306 uint8_t ohdr[60 + 8]; /* max IP header plus 8 bytes of payload for icmp */ 307 305 308 STAM_PROFILE_START(&pData->StatTCP_input, counter_input); 306 309 … … 324 327 tp = sototcpcb(so); 325 328 m = so->so_m; 326 327 329 so->so_m = 0; 330 331 if (RT_LIKELY(so->so_ohdr != NULL)) 332 { 333 RTMemFree(so->so_ohdr); 334 so->so_ohdr = NULL; 335 } 336 328 337 ti = so->so_ti; 329 338 … … 347 356 348 357 tcpstat.tcps_rcvtotal++; 358 359 ip = mtod(m, struct ip *); 360 361 /* ip_input() subtracts iphlen from ip::ip_len */ 362 AssertStmt((ip->ip_len + iphlen == m_length(m, NULL)), goto drop); 363 if (RT_UNLIKELY(ip->ip_len < sizeof(struct tcphdr))) 364 { 365 /* tcps_rcvshort++; */ 366 goto drop; 367 } 368 369 /* 370 * Save a copy of the IP header in case we want to restore it for 371 * sending an ICMP error message in response. 372 * 373 * XXX: This function should really be fixed to not strip IP 374 * options, to not overwrite IP header and to use "tlen" local 375 * variable (instead of ti->ti_len), then "m" could be passed to 376 * icmp_error() directly. 377 */ 378 ohdrlen = iphlen + 8; 379 m_copydata(m, 0, ohdrlen, (caddr_t)ohdr); 380 save_ip = (struct ip *)ohdr; 381 save_ip->ip_len += iphlen; /* undo change by ip_input() */ 382 383 349 384 /* 350 385 * Get IP and TCP header together in first mbuf. … … 357 392 iphlen = sizeof(struct ip); 358 393 } 359 /* XXX Check if too short */360 361 362 /*363 * Save a copy of the IP header in case we want restore it364 * for sending an ICMP error message in response.365 */366 ip = mtod(m, struct ip *);367 /*368 * (vvl) ip_input substracts IP header length from ip->ip_len value.369 * here we do the test the same as input method of UDP protocol.370 */371 Assert((ip->ip_len + iphlen == m_length(m, NULL)));372 save_ip = *ip;373 save_ip.ip_len+= iphlen;374 394 375 395 /* … … 802 822 m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 803 823 m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); 804 *ip = save_ip;824 *ip = *save_ip; 805 825 icmp_error(pData, m, ICMP_UNREACH, code, 0, strerror(errno)); 806 826 tp->t_socket->so_m = NULL; … … 818 838 so->so_m = m; 819 839 so->so_ti = ti; 840 so->so_ohdr = RTMemDup(ohdr, ohdrlen); 820 841 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 821 842 TCP_STATE_SWITCH_TO(tp, TCPS_SYN_RECEIVED); … … 1743 1764 } 1744 1765 1766 1767 void 1768 tcp_fconnect_failed(PNATState pData, struct socket *so, int sockerr) 1769 { 1770 struct tcpcb *tp; 1771 int code; 1772 1773 Log2(("NAT: connect error %d %R[natsock]\n", sockerr, so)); 1774 1775 Assert(so->so_state & SS_ISFCONNECTING); 1776 so->so_state = SS_NOFDREF; 1777 1778 if (sockerr == ECONNREFUSED || sockerr == ECONNRESET) 1779 { 1780 /* hand off to tcp_input():cont_conn to send RST */ 1781 TCP_INPUT(pData, NULL, 0, so); 1782 return; 1783 } 1784 1785 tp = sototcpcb(so); 1786 if (RT_UNLIKELY(tp == NULL)) /* should never happen */ 1787 { 1788 LogRel(("NAT: tp == NULL %R[natsock]\n", so)); 1789 sofree(pData, so); 1790 return; 1791 } 1792 1793 if (sockerr == ENETUNREACH || sockerr == ENETDOWN) 1794 code = ICMP_UNREACH_NET; 1795 else if (sockerr == EHOSTUNREACH || sockerr == EHOSTDOWN) 1796 code = ICMP_UNREACH_HOST; 1797 else 1798 code = -1; 1799 1800 if (code >= 0) 1801 { 1802 struct ip *oip; 1803 size_t ohdrlen; 1804 struct mbuf *m; 1805 1806 if (RT_UNLIKELY(so->so_ohdr == NULL)) 1807 goto out; 1808 1809 oip = (struct ip *)so->so_ohdr; 1810 ohdrlen = oip->ip_hl * 4 + 8; 1811 1812 m = m_gethdr(pData, M_NOWAIT, MT_HEADER); 1813 if (RT_UNLIKELY(m == NULL)) 1814 goto out; 1815 1816 m_copyback(pData, m, 0, ohdrlen, (caddr_t)so->so_ohdr); 1817 m->m_pkthdr.header = mtod(m, void *); 1818 1819 icmp_error(pData, m, ICMP_UNREACH, code, 0, NULL); 1820 } 1821 1822 out: 1823 tcp_close(pData, tp); 1824 } 1825 1826 1745 1827 void 1746 1828 tcp_dooptions(PNATState pData, struct tcpcb *tp, u_char *cp, int cnt, struct tcpiphdr *ti)
Note:
See TracChangeset
for help on using the changeset viewer.