Changeset 15453 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Dec 13, 2008 10:35:53 PM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/ip.h
r15450 r15453 38 38 #define _IP_H_ 39 39 40 #ifdef VBOX_WITH_BSD_REASS 41 # include "queue.h" 42 #endif 40 #include "queue.h" 43 41 44 42 #ifdef WORDS_BIGENDIAN … … 173 171 # include <sys/types32.h> 174 172 #else 175 # if SIZEOF_CHAR_P == 4176 173 typedef caddr_t caddr32_t; 177 # else178 # if !defined(VBOX_WITH_BSD_REASS)179 typedef u_int32_t caddr32_t;180 # else /* VBOX_WITH_BSD_REASS */181 typedef caddr_t caddr32_t;182 # endif /* VBOX_WITH_BSD_REASS */183 # endif184 174 #endif 185 175 … … 197 187 struct ipovly 198 188 { 199 #if !defined(VBOX_WITH_BSD_REASS)200 caddr32_t ih_next;201 caddr32_t ih_prev; /* for protocol sequence q's */202 u_int8_t ih_x1; /* (unused) */203 #else /* VBOX_WITH_BSD_REASS */204 189 u_int8_t ih_x1[9]; /* (unused) */ 205 #endif /* VBOX_WITH_BSD_REASS */206 190 u_int8_t ih_pr; /* protocol */ 207 191 u_int16_t ih_len; /* protocol length */ … … 219 203 struct ipq_t 220 204 { 221 #ifndef VBOX_WITH_BSD_REASS222 ipqp_32 next;223 ipqp_32 prev; /* to other reass headers */224 #else /* VBOX_WITH_BSD_REASS */225 205 TAILQ_ENTRY(ipq_t) ipq_list; 226 #endif /* VBOX_WITH_BSD_REASS */227 206 u_int8_t ipq_ttl; /* time for reass q to live */ 228 207 u_int8_t ipq_p; /* protocol of this fragment */ 229 208 u_int16_t ipq_id; /* sequence id for reassembly */ 230 #ifndef VBOX_WITH_BSD_REASS231 ipasfragp_32 ipq_next;232 ipasfragp_32 ipq_prev; /* to ip headers of fragments */233 #else /* VBOX_WITH_BSD_REASS */234 209 struct mbuf *ipq_frags; /* to ip headers of fragments */ 235 210 uint8_t ipq_nfrags; /* # of fragments in this packet */ 236 #endif /* VBOX_WITH_BSD_REASS */237 211 struct in_addr ipq_src; 238 212 struct in_addr ipq_dst; 239 213 }; 240 214 241 #ifdef VBOX_WITH_BSD_REASS242 215 243 216 /* … … 250 223 (((((x) & 0xF) | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK) 251 224 TAILQ_HEAD(ipqhead,ipq_t); 252 253 #else /* !VBOX_WITH_BSD_REASS */254 255 /*256 * Ip header, when holding a fragment.257 *258 * Note: ipf_next must be at same offset as ipq_next above259 */260 struct ipasfrag261 {262 #ifdef WORDS_BIGENDIAN263 # ifdef _MSC_VER264 uint8_t ip_v:4;265 uint8_t ip_hl:4;266 # else267 unsigned ip_v:4;268 unsigned ip_hl:4;269 # endif270 #else271 # ifdef _MSC_VER272 uint8_t ip_hl:4;273 uint8_t ip_v:4;274 # else275 unsigned ip_hl:4;276 unsigned ip_v:4;277 # endif278 #endif279 u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit280 * to avoid destroying tos (PPPDTRuu);281 * copied from (ip_off & IP_MF) */282 u_int16_t ip_len;283 u_int16_t ip_id;284 u_int16_t ip_off;285 u_int8_t ip_ttl;286 u_int8_t ip_p;287 u_int16_t ip_sum;288 ipasfragp_32 ipf_next; /* next fragment */289 ipasfragp_32 ipf_prev; /* previous fragment */290 };291 AssertCompileSize(struct ipasfrag, 20);292 293 #endif /* !VBOX_WITH_BSD_REASS */294 225 295 226 /* -
trunk/src/VBox/Devices/Network/slirp/ip_input.c
r15450 r15453 54 54 ip_init(PNATState pData) 55 55 { 56 #ifndef VBOX_WITH_BSD_REASS57 ipq.next = ipq.prev = ptr_to_u32(pData, &ipq);58 #else /* !VBOX_WITH_BSD_REASS */59 56 int i = 0; 60 57 for (i = 0; i < IPREASS_NHASH; ++i) … … 63 60 maxfragsperpacket = 16; 64 61 nipq = 0; 65 #endif /* VBOX_WITH_BSD_REASS */66 62 ip_currid = tt.tv_sec & 0xffff; 67 63 udp_init(pData); … … 163 159 * XXX This should fail, don't fragment yet 164 160 */ 165 #ifndef VBOX_WITH_BSD_REASS166 if (ip->ip_off &~ IP_DF)167 {168 register struct ipq_t *fp;169 /*170 * Look for queue of fragments171 * of this datagram.172 */173 for (fp = u32_to_ptr(pData, ipq.next, struct ipq_t *);174 fp != &ipq;175 fp = u32_to_ptr(pData, fp->next, struct ipq_t *))176 if ( ip->ip_id == fp->ipq_id177 && ip->ip_src.s_addr == fp->ipq_src.s_addr178 && ip->ip_dst.s_addr == fp->ipq_dst.s_addr179 && ip->ip_p == fp->ipq_p)180 goto found;181 fp = 0;182 found:183 184 /*185 * Adjust ip_len to not reflect header,186 * set ip_mff if more fragments are expected,187 * convert offset of this to bytes.188 */189 ip->ip_len -= hlen;190 if (ip->ip_off & IP_MF)191 ((struct ipasfrag *)ip)->ipf_mff |= 1;192 else193 ((struct ipasfrag *)ip)->ipf_mff &= ~1;194 195 ip->ip_off <<= 3;196 197 /*198 * If datagram marked as having more fragments199 * or if this is not the first fragment,200 * attempt reassembly; if it succeeds, proceed.201 */202 if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off)203 {204 ipstat.ips_fragments++;205 ip = ip_reass(pData, (struct ipasfrag *)ip, fp);206 if (ip == 0)207 return;208 ipstat.ips_reassembled++;209 m = dtom(pData, ip);210 }211 else212 if (fp)213 ip_freef(pData, fp);214 215 }216 else217 ip->ip_len -= hlen;218 #else /* !VBOX_WITH_BSD_REASS */219 161 if (ip->ip_off & (IP_MF | IP_OFFMASK)) 220 162 { … … 227 169 else 228 170 ip->ip_len -= hlen; 229 #endif /* VBOX_WITH_BSD_REASS */230 171 231 172 /* … … 253 194 return; 254 195 } 255 256 #ifndef VBOX_WITH_BSD_REASS257 /*258 * Take incoming datagram fragment and try to259 * reassemble it into whole datagram. If a chain for260 * reassembly of this datagram already exists, then it261 * is given as fp; otherwise have to make a chain.262 */263 struct ip *264 ip_reass(PNATState pData, register struct ipasfrag *ip, register struct ipq_t *fp)265 {266 register struct mbuf *m = dtom(pData, ip);267 register struct ipasfrag *q;268 int hlen = ip->ip_hl << 2;269 int i, next;270 271 DEBUG_CALL("ip_reass");272 DEBUG_ARG("ip = %lx", (long)ip);273 DEBUG_ARG("fp = %lx", (long)fp);274 DEBUG_ARG("m = %lx", (long)m);275 276 /*277 * Presence of header sizes in mbufs278 * would confuse code below.279 * Fragment m_data is concatenated.280 */281 m->m_data += hlen;282 m->m_len -= hlen;283 284 /*285 * If first fragment to arrive, create a reassembly queue.286 */287 if (fp == 0)288 {289 struct mbuf *t;290 if ((t = m_get(pData)) == NULL) goto dropfrag;291 fp = mtod(t, struct ipq_t *);292 insque_32(pData, fp, &ipq);293 fp->ipq_ttl = IPFRAGTTL;294 fp->ipq_p = ip->ip_p;295 fp->ipq_id = ip->ip_id;296 fp->ipq_next = fp->ipq_prev = ptr_to_u32(pData, (struct ipasfrag *)fp);297 fp->ipq_src = ((struct ip *)ip)->ip_src;298 fp->ipq_dst = ((struct ip *)ip)->ip_dst;299 q = (struct ipasfrag *)fp;300 goto insert;301 }302 303 /*304 * Find a segment which begins after this one does.305 */306 for (q = u32_to_ptr(pData, fp->ipq_next, struct ipasfrag *);307 q != (struct ipasfrag *)fp;308 q = u32_to_ptr(pData, q->ipf_next, struct ipasfrag *))309 if (q->ip_off > ip->ip_off)310 break;311 312 /*313 * If there is a preceding segment, it may provide some of314 * our data already. If so, drop the data from the incoming315 * segment. If it provides all of our data, drop us.316 */317 if (u32_to_ptr(pData, q->ipf_prev, struct ipq_t *) != fp)318 {319 i = (u32_to_ptr(pData, q->ipf_prev, struct ipasfrag *))->ip_off +320 (u32_to_ptr(pData, q->ipf_prev, struct ipasfrag *))->ip_len - ip->ip_off;321 if (i > 0)322 {323 if (i >= ip->ip_len)324 goto dropfrag;325 m_adj(dtom(pData, ip), i);326 ip->ip_off += i;327 ip->ip_len -= i;328 }329 }330 331 /*332 * While we overlap succeeding segments trim them or,333 * if they are completely covered, dequeue them.334 */335 while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off)336 {337 i = (ip->ip_off + ip->ip_len) - q->ip_off;338 if (i < q->ip_len) {339 q->ip_len -= i;340 q->ip_off += i;341 m_adj(dtom(pData, q), i);342 break;343 }344 q = u32_to_ptr(pData, q->ipf_next, struct ipasfrag *);345 m_freem(pData, dtom(pData, u32_to_ptr(pData, q->ipf_prev, struct ipasfrag *)));346 ip_deq(pData, u32_to_ptr(pData, q->ipf_prev, struct ipasfrag *));347 }348 349 insert:350 /*351 * Stick new segment in its place;352 * check for complete reassembly.353 */354 ip_enq(pData, ip, u32_to_ptr(pData, q->ipf_prev, struct ipasfrag *));355 next = 0;356 for (q = u32_to_ptr(pData, fp->ipq_next, struct ipasfrag *);357 q != (struct ipasfrag *)fp;358 q = u32_to_ptr(pData, q->ipf_next, struct ipasfrag *))359 {360 if (q->ip_off != next)361 return (0);362 next += q->ip_len;363 }364 if (u32_to_ptr(pData, q->ipf_prev, struct ipasfrag *)->ipf_mff & 1)365 return (0);366 367 /*368 * Reassembly is complete; concatenate fragments.369 */370 q = u32_to_ptr(pData, fp->ipq_next, struct ipasfrag *);371 m = dtom(pData, q);372 373 q = u32_to_ptr(pData, q->ipf_next, struct ipasfrag *);374 while (q != (struct ipasfrag *)fp)375 {376 struct mbuf *t;377 t = dtom(pData, q);378 q = u32_to_ptr(pData, q->ipf_next, struct ipasfrag *);379 m_cat(pData, m, t);380 }381 382 /*383 * Create header for new ip packet by384 * modifying header of first packet;385 * dequeue and discard fragment reassembly header.386 * Make header visible.387 */388 ip = u32_to_ptr(pData, fp->ipq_next, struct ipasfrag *);389 390 /*391 * If the fragments concatenated to an mbuf that's392 * bigger than the total size of the fragment, then and393 * m_ext buffer was alloced. But fp->ipq_next points to394 * the old buffer (in the mbuf), so we must point ip395 * into the new buffer.396 */397 if (m->m_flags & M_EXT)398 {399 int delta;400 delta = (char *)ip - m->m_dat;401 ip = (struct ipasfrag *)(m->m_ext + delta);402 }403 404 /* DEBUG_ARG("ip = %lx", (long)ip);405 * ip=(struct ipasfrag *)m->m_data; */406 407 ip->ip_len = next;408 ip->ipf_mff &= ~1;409 ((struct ip *)ip)->ip_src = fp->ipq_src;410 ((struct ip *)ip)->ip_dst = fp->ipq_dst;411 remque_32(pData, fp);412 (void) m_free(pData, dtom(pData, fp));413 m = dtom(pData, ip);414 m->m_len += (ip->ip_hl << 2);415 m->m_data -= (ip->ip_hl << 2);416 417 return ((struct ip *)ip);418 419 dropfrag:420 ipstat.ips_fragdropped++;421 m_freem(pData, m);422 return (0);423 }424 425 /*426 * Free a fragment reassembly header and all427 * associated datagrams.428 */429 void430 ip_freef(PNATState pData, struct ipq_t *fp)431 {432 register struct ipasfrag *q, *p;433 434 for (q = u32_to_ptr(pData, fp->ipq_next, struct ipasfrag *);435 q != (struct ipasfrag *)fp;436 q = p)437 {438 p = u32_to_ptr(pData, q->ipf_next, struct ipasfrag *);439 ip_deq(pData, q);440 m_freem(pData, dtom(pData, q));441 }442 remque_32(pData, fp);443 (void) m_free(pData, dtom(pData, fp));444 }445 446 #else /* VBOX_WITH_BSD_REASS */447 196 448 197 struct mbuf * … … 760 509 nipq--; 761 510 } 762 #endif /* VBOX_WITH_BSD_REASS */763 764 #ifndef VBOX_WITH_BSD_REASS765 /*766 * Put an ip fragment on a reassembly chain.767 * Like insque, but pointers in middle of structure.768 */769 void770 ip_enq(PNATState pData, register struct ipasfrag *p, register struct ipasfrag *prev)771 {772 DEBUG_CALL("ip_enq");773 DEBUG_ARG("prev = %lx", (long)prev);774 p->ipf_prev = ptr_to_u32(pData, prev);775 p->ipf_next = prev->ipf_next;776 u32_to_ptr(pData, prev->ipf_next, struct ipasfrag *)->ipf_prev = ptr_to_u32(pData, p);777 prev->ipf_next = ptr_to_u32(pData, p);778 }779 780 /*781 * To ip_enq as remque is to insque.782 */783 void784 ip_deq(PNATState pData, register struct ipasfrag *p)785 {786 struct ipasfrag *prev = u32_to_ptr(pData, p->ipf_prev, struct ipasfrag *);787 struct ipasfrag *next = u32_to_ptr(pData, p->ipf_next, struct ipasfrag *);788 u32ptr_done(pData, prev->ipf_next, p);789 prev->ipf_next = p->ipf_next;790 next->ipf_prev = p->ipf_prev;791 }792 #endif /* !VBOX_WITH_BSD_REASS */793 511 794 512 /* … … 802 520 register struct ipq_t *fp; 803 521 804 #ifndef VBOX_WITH_BSD_REASS805 DEBUG_CALL("ip_slowtimo");806 807 fp = u32_to_ptr(pData, ipq.next, struct ipq_t *);808 if (fp == 0)809 return;810 811 while (fp != &ipq)812 {813 --fp->ipq_ttl;814 fp = u32_to_ptr(pData, fp->next, struct ipq_t *);815 if (u32_to_ptr(pData, fp->prev, struct ipq_t *)->ipq_ttl == 0)816 {817 ipstat.ips_fragtimeout++;818 ip_freef(pData, u32_to_ptr(pData, fp->prev, struct ipq_t *));819 }820 }821 #else /* VBOX_WITH_BSD_REASS */822 522 /* XXX: the fragment expiration is the same but requier 823 523 * additional loop see (see ip_input.c in FreeBSD tree) … … 855 555 } 856 556 } 857 #endif /* VBOX_WITH_BSD_REASS */858 557 } 859 558 -
trunk/src/VBox/Devices/Network/slirp/mbuf.c
r15450 r15453 110 110 if (m->m_flags & M_DOFREE) 111 111 { 112 u32ptr_done(pData, ptr_to_u32(pData, m), m);113 112 free(m); 114 113 mbuf_alloced--; -
trunk/src/VBox/Devices/Network/slirp/mbuf.h
r14964 r15453 74 74 caddr_t mh_data; /* Location of data */ 75 75 int mh_len; /* Amount of data in this mbuf */ 76 #ifdef VBOX_WITH_BSD_REASS 77 void *header; /*XXX: in real BSD sources this field lays in pkthdr structure*/ 78 #endif 76 void *header; /*XXX: in real BSD sources this field lays in pkthdr structure*/ 79 77 }; 80 78 … … 126 124 #define M_DOFREE 0x08 /* when m_free is called on the mbuf, free() 127 125 * it rather than putting it on the free list */ 128 #ifdef VBOX_WITH_BSD_REASS 129 #define M_FRAG 0x0800 /* packet is a fragment of a larger packet */ 130 #define M_FIRSTFRAG 0x1000 /* paket is first fragment */ 131 #define M_LASTFRAG 0x2000 /* paket is last fragment */ 132 #endif /* VBOX_WITH_BSD_REASS */ 126 #define M_FRAG 0x0800 /* packet is a fragment of a larger packet */ 127 #define M_FIRSTFRAG 0x1000 /* paket is first fragment */ 128 #define M_LASTFRAG 0x2000 /* paket is last fragment */ 133 129 134 130 extern int mbuf_alloced; -
trunk/src/VBox/Devices/Network/slirp/misc.c
r14964 r15453 29 29 our_addr.s_addr = loopback_addr.s_addr; 30 30 } 31 32 #if SIZEOF_CHAR_P == 8 && !defined(VBOX_WITH_BSD_REASS)33 34 struct quehead_3235 {36 u_int32_t qh_link;37 u_int32_t qh_rlink;38 };39 40 void41 insque_32(PNATState pData, void *a, void *b)42 {43 register struct quehead_32 *element = (struct quehead_32 *) a;44 register struct quehead_32 *head = (struct quehead_32 *) b;45 struct quehead_32 *link = u32_to_ptr(pData, head->qh_link, struct quehead_32 *);46 47 element->qh_link = head->qh_link;48 element->qh_rlink = ptr_to_u32(pData, head);49 Assert(link->qh_rlink == element->qh_rlink);50 link->qh_rlink = head->qh_link = ptr_to_u32(pData, element);51 }52 53 void54 remque_32(PNATState pData, void *a)55 {56 register struct quehead_32 *element = (struct quehead_32 *) a;57 struct quehead_32 *link = u32_to_ptr(pData, element->qh_link, struct quehead_32 *);58 struct quehead_32 *rlink = u32_to_ptr(pData, element->qh_rlink, struct quehead_32 *);59 60 u32ptr_done(pData, link->qh_rlink, element);61 link->qh_rlink = element->qh_rlink;62 rlink->qh_link = element->qh_link;63 element->qh_rlink = 0;64 }65 66 #endif /* SIZEOF_CHAR_P == 8 && !VBOX_WITH_BSD_REASS */67 31 68 32 struct quehead -
trunk/src/VBox/Devices/Network/slirp/slirp.c
r15384 r15453 342 342 pData->fPassDomain = fPassDomain; 343 343 pData->pvUser = pvUser; 344 #if ARCH_BITS == 64 && !defined(VBOX_WITH_BSD_REASS)345 pData->cpvHashUsed = 1;346 #endif347 344 tftp_prefix = pszTFTPPrefix; 348 345 bootp_filename = pszBootFile; … … 446 443 RTStrFree((char *)(void *)pData->pszDomain); 447 444 448 #if ARCH_BITS == 64 && !defined(VBOX_WITH_BSD_REASS)449 LogRel(("NAT: cpvHashUsed=%RU32 cpvHashCollisions=%RU32 cpvHashInserts=%RU64 cpvHashDone=%RU64\n",450 pData->cpvHashUsed, pData->cpvHashCollisions, pData->cpvHashInserts, pData->cpvHashDone));451 #endif452 453 445 #ifdef VBOX_WITH_SLIRP_ICMP 454 446 # ifdef RT_OS_WINDOWS … … 522 514 int error; 523 515 #endif 524 #ifdef VBOX_WITH_BSD_REASS525 516 int i; 526 #endif /* VBOX_WITH_BSD_REASS */527 517 528 518 STAM_REL_PROFILE_START(&pData->StatFill, a); … … 540 530 * in the fragment queue, or there are TCP connections active 541 531 */ 542 #ifndef VBOX_WITH_BSD_REASS543 do_slowtimo = ((tcb.so_next != &tcb)544 || ((struct ipasfrag *)&ipq != u32_to_ptr(pData, ipq.next, struct ipasfrag *)));545 #else /* !VBOX_WITH_BSD_REASS */546 532 /* XXX: 547 533 * triggering of fragment expiration should be the same but use new macroses … … 559 545 } 560 546 } 561 #endif /* VBOX_WITH_BSD_REASS */562 547 ICMP_ENGAGE_EVENT(&pData->icmp_socket, readfds); 563 548 -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r15357 r15453 295 295 void ip_init _P((PNATState)); 296 296 void ip_input _P((PNATState, struct mbuf *)); 297 #ifndef VBOX_WITH_BSD_REASS298 struct ip * ip_reass _P((PNATState, register struct ipasfrag *, register struct ipq_t *));299 void ip_freef _P((PNATState, struct ipq_t *));300 void ip_enq _P((PNATState, register struct ipasfrag *, register struct ipasfrag *));301 void ip_deq _P((PNATState, register struct ipasfrag *));302 #else /* !VBOX_WITH_BSD_REASS */303 297 struct mbuf * ip_reass _P((PNATState, register struct mbuf *)); 304 298 void ip_freef _P((PNATState, struct ipqhead *, struct ipq_t *)); 305 #endif /* VBOX_WITH_BSD_REASS */306 299 void ip_slowtimo _P((PNATState)); 307 300 void ip_stripoptions _P((register struct mbuf *, struct mbuf *)); … … 311 304 312 305 /* tcp_input.c */ 313 #ifndef VBOX_WITH_BSD_REASS314 int tcp_reass _P((PNATState, register struct tcpcb *, register struct tcpiphdr *, struct mbuf *));315 #else /* !VBOX_WITH_BSD_REASS */316 306 int tcp_reass _P((PNATState, struct tcpcb *, struct tcphdr *, int *, struct mbuf *)); 317 #endif /* VBOX_WITH_BSD_REASS */318 307 void tcp_input _P((PNATState, register struct mbuf *, int, struct socket *)); 319 308 void tcp_dooptions _P((PNATState, struct tcpcb *, u_char *, int, struct tcpiphdr *)); -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r15195 r15453 74 74 /* Stuff from ip_input.c */ 75 75 struct ipstat_t ipstat; 76 #ifndef VBOX_WITH_BSD_REASS77 struct ipq_t ipq;78 #else /* !VBOX_WITH_BSD_REASS */79 76 struct ipqhead ipq[IPREASS_NHASH]; 80 77 int maxnipq; /* Administrative limit on # of reass queues*/ 81 78 int maxfragsperpacket; /* Maximum number of IPv4 fragments allowed per packet */ 82 79 int nipq; /* total number of reass queues */ 83 #endif /* VBOX_WITH_BSD_REASS */84 80 uint16_t ip_currid; 85 81 /* Stuff from mbuf.c */ … … 110 106 struct socket *tcp_last_so; 111 107 tcp_seq tcp_iss; 112 #if ARCH_BITS == 64 && !defined(VBOX_WITH_BSD_REASS)113 /* Stuff from tcp_subr.c */114 void *apvHash[16384];115 uint32_t cpvHashUsed;116 uint32_t cpvHashCollisions;117 uint64_t cpvHashInserts;118 uint64_t cpvHashDone;119 #endif /* ARCH_BITS == 64 && !defined(VBOX_WITH_BSD_REASS) */120 108 /* Stuff from tcp_timer.c */ 121 109 struct tcpstat_t tcpstat; 122 110 uint32_t tcp_now; 123 #ifdef VBOX_WITH_BSD_REASS124 111 int tcp_reass_qsize; 125 112 int tcp_reass_maxqlen; 126 113 int tcp_reass_maxseg; 127 114 int tcp_reass_overflows; 128 #endif /* VBOX_WITH_BSD_REASS */129 115 /* Stuff from tftp.c */ 130 116 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; … … 256 242 #define udp_last_so pData->udp_last_so 257 243 258 #ifdef VBOX_WITH_BSD_REASS259 260 244 #define maxfragsperpacket pData->maxfragsperpacket 261 245 #define maxnipq pData->maxnipq … … 267 251 #define tcp_reass_overflows pData->tcp_reass_overflows 268 252 269 #else /* ! VBOX_WITH_BSD_REASS */270 271 #if SIZEOF_CHAR_P != 4272 extern void VBoxU32PtrDone(PNATState pData, void *pv, uint32_t iHint);273 extern uint32_t VBoxU32PtrHashSlow(PNATState pData, void *pv);274 275 /** Hash the pointer, inserting it if need be. */276 DECLINLINE(uint32_t) VBoxU32PtrHash(PNATState pData, void *pv)277 {278 uint32_t i = ((uintptr_t)pv >> 3) % RT_ELEMENTS(pData->apvHash);279 if (RT_LIKELY(pData->apvHash[i] == pv && pv))280 return i;281 return VBoxU32PtrHashSlow(pData, pv);282 }283 /** Lookup the hash value. */284 DECLINLINE(void *) VBoxU32PtrLookup(PNATState pData, uint32_t i)285 {286 void *pv;287 Assert(i < RT_ELEMENTS(pData->apvHash));288 pv = pData->apvHash[i];289 Assert(pv || !i);290 return pv;291 }292 #endif293 294 #endif295 296 253 #endif /* !_slirp_state_h_ */ -
trunk/src/VBox/Devices/Network/slirp/tcp_input.c
r14638 r15453 53 53 #define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) 54 54 55 #ifndef VBOX_WITH_BSD_REASS56 /*57 * Insert segment ti into reassembly queue of tcp with58 * control block tp. Return TH_FIN if reassembly now includes59 * a segment with FIN. The macro form does the common case inline60 * (segment is the next to be received on an established connection,61 * and the queue is empty), avoiding linkage into and removal62 * from the queue and repetition of various conversions.63 * Set DELACK for segments received in order, but ack immediately64 * when segments are out of order (so fast retransmit can work).65 */66 #ifdef TCP_ACK_HACK67 #define TCP_REASS(pData, tp, ti, m, so, flags) {\68 if ((ti)->ti_seq == (tp)->rcv_nxt && \69 u32_to_ptr((pData), (tp)->seg_next, struct tcpcb *) == (tp) && \70 (tp)->t_state == TCPS_ESTABLISHED) {\71 if (ti->ti_flags & TH_PUSH) \72 tp->t_flags |= TF_ACKNOW; \73 else \74 tp->t_flags |= TF_DELACK; \75 (tp)->rcv_nxt += (ti)->ti_len; \76 flags = (ti)->ti_flags & TH_FIN; \77 tcpstat.tcps_rcvpack++;\78 tcpstat.tcps_rcvbyte += (ti)->ti_len;\79 if (so->so_emu) { \80 if (tcp_emu((pData), (so),(m))) sbappend((pData), (so), (m)); \81 } else \82 sbappend((pData), (so), (m)); \83 /* sorwakeup(so); */ \84 } else {\85 (flags) = tcp_reass((pData), (tp), (ti), (m)); \86 tp->t_flags |= TF_ACKNOW; \87 } \88 }89 #else90 #define TCP_REASS(pData, tp, ti, m, so, flags) { \91 if ((ti)->ti_seq == (tp)->rcv_nxt && \92 u32_to_ptr((pData), (tp)->seg_next, struct tcpcb *) == (tp) && \93 (tp)->t_state == TCPS_ESTABLISHED) { \94 tp->t_flags |= TF_DELACK; \95 (tp)->rcv_nxt += (ti)->ti_len; \96 flags = (ti)->ti_flags & TH_FIN; \97 tcpstat.tcps_rcvpack++;\98 tcpstat.tcps_rcvbyte += (ti)->ti_len;\99 if (so->so_emu) { \100 if (tcp_emu((pData), (so),(m))) sbappend((pData), (so), (m)); \101 } else \102 sbappend((pData), (so), (m)); \103 /* sorwakeup(so); */ \104 } else { \105 (flags) = tcp_reass((pData), (tp), (ti), (m)); \106 tp->t_flags |= TF_ACKNOW; \107 } \108 }109 #endif110 111 int112 tcp_reass(PNATState pData, register struct tcpcb *tp, register struct tcpiphdr *ti, struct mbuf *m)113 {114 register struct tcpiphdr *q;115 struct socket *so = tp->t_socket;116 int flags;117 118 /*119 * Call with ti==0 after become established to120 * force pre-ESTABLISHED data up to user socket.121 */122 if (ti == 0)123 goto present;124 125 /*126 * Find a segment which begins after this one does.127 */128 for (q = u32_to_ptr(pData, tp->seg_next, struct tcpiphdr *); q != (struct tcpiphdr *)tp;129 q = u32_to_ptr(pData, q->ti_next, struct tcpiphdr *))130 if (SEQ_GT(q->ti_seq, ti->ti_seq))131 break;132 133 /*134 * If there is a preceding segment, it may provide some of135 * our data already. If so, drop the data from the incoming136 * segment. If it provides all of our data, drop us.137 */138 if (u32_to_ptr(pData, q->ti_prev, struct tcpiphdr *) != (struct tcpiphdr *)tp) {139 register int i;140 q = u32_to_ptr(pData, q->ti_prev, struct tcpiphdr *);141 /* conversion to int (in i) handles seq wraparound */142 i = q->ti_seq + q->ti_len - ti->ti_seq;143 if (i > 0) {144 if (i >= ti->ti_len) {145 tcpstat.tcps_rcvduppack++;146 tcpstat.tcps_rcvdupbyte += ti->ti_len;147 m_freem(pData, m);148 /*149 * Try to present any queued data150 * at the left window edge to the user.151 * This is needed after the 3-WHS152 * completes.153 */154 goto present; /* ??? */155 }156 m_adj(m, i);157 ti->ti_len -= i;158 ti->ti_seq += i;159 }160 q = u32_to_ptr(pData, q->ti_next, struct tcpiphdr *);161 }162 tcpstat.tcps_rcvoopack++;163 tcpstat.tcps_rcvoobyte += ti->ti_len;164 REASS_MBUF_SET(ti, m); /* XXX */165 166 /*167 * While we overlap succeeding segments trim them or,168 * if they are completely covered, dequeue them.169 */170 while (q != (struct tcpiphdr *)tp) {171 register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;172 if (i <= 0)173 break;174 if (i < q->ti_len) {175 q->ti_seq += i;176 q->ti_len -= i;177 m_adj(REASS_MBUF_GET(q), i);178 break;179 }180 q = u32_to_ptr(pData, q->ti_next, struct tcpiphdr *);181 m = REASS_MBUF_GET(u32_to_ptr(pData, q->ti_prev, struct tcpiphdr *));182 remque_32(pData, u32_to_ptr(pData, q->ti_prev, struct tcpiphdr *));183 m_freem(pData, m);184 }185 186 /*187 * Stick new segment in its place.188 */189 insque_32(pData, ti, u32_to_ptr(pData, q->ti_prev, struct tcpiphdr *));190 191 present:192 /*193 * Present data to user, advancing rcv_nxt through194 * completed sequence space.195 */196 if (!TCPS_HAVEESTABLISHED(tp->t_state))197 return (0);198 ti = u32_to_ptr(pData, tp->seg_next, struct tcpiphdr *);199 if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)200 return (0);201 if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)202 return (0);203 do {204 tp->rcv_nxt += ti->ti_len;205 flags = ti->ti_flags & TH_FIN;206 remque_32(pData, ti);207 m = REASS_MBUF_GET(ti); /* XXX */208 ti = u32_to_ptr(pData, ti->ti_next, struct tcpiphdr *);209 /* if (so->so_state & SS_FCANTRCVMORE) */210 if (so->so_state & SS_FCANTSENDMORE)211 m_freem(pData, m);212 else {213 if (so->so_emu) {214 if (tcp_emu(pData, so,m)) sbappend(pData, so, m);215 } else216 sbappend(pData, so, m);217 }218 } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);219 /* sorwakeup(so); */220 return (flags);221 }222 223 #else /* VBOX_WITH_BSD_REASS */224 225 55 #ifndef TCP_ACK_HACK 226 56 #define DELAY_ACK(tp, ti) \ … … 400 230 return (flags); 401 231 } 402 #endif /* VBOX_WITH_BSD_REASS */403 232 404 233 /* … … 470 299 */ 471 300 tlen = ((struct ip *)ti)->ip_len; 472 #if !defined(VBOX_WITH_BSD_REASS)473 ti->ti_next = ti->ti_prev = 0;474 ti->ti_x1 = 0;475 #else476 301 memset(ti->ti_x1, 0, 9); 477 #endif478 302 ti->ti_len = htons((u_int16_t)tlen); 479 303 len = sizeof(struct ip ) + tlen; … … 723 547 } 724 548 } else if (ti->ti_ack == tp->snd_una && 725 #ifndef VBOX_WITH_BSD_REASS726 u32_to_ptr(pData, tp->seg_next, struct tcpcb *) == tp &&727 #else /* VBOX_WITH_BSD_REASS */728 549 LIST_FIRST(&tp->t_segq) && 729 #endif /* VBOX_WITH_BSD_REASS */730 550 ti->ti_len <= sbspace(&so->so_rcv)) { 731 551 /* … … 927 747 * } 928 748 */ 929 #ifndef VBOX_WITH_BSD_REASS930 (void) tcp_reass(pData, tp, (struct tcpiphdr *)0,931 (struct mbuf *)0);932 #else /* VBOX_WITH_BSD_REASS */933 749 (void) tcp_reass(pData, tp, (struct tcphdr *)0, NULL, (struct mbuf *)0); 934 #endif /* VBOX_WITH_BSD_REASS */935 750 /* 936 751 * if we didn't have to retransmit the SYN, … … 1187 1002 * } 1188 1003 */ 1189 #ifndef VBOX_WITH_BSD_REASS1190 (void) tcp_reass(pData, tp, (struct tcpiphdr *)0, (struct mbuf *)0);1191 #else /* VBOX_WITH_BSD_REASS */1192 1004 (void) tcp_reass(pData, tp, (struct tcphdr *)0, (int *)0, (struct mbuf *)0); 1193 #endif /*VBOX_WITH_BSD_REASS*/1194 1005 tp->snd_wl1 = ti->ti_seq - 1; 1195 1006 /* Avoid ack processing; snd_una==ti_ack => dup ack */ … … 1505 1316 if ((ti->ti_len || (tiflags&TH_FIN)) && 1506 1317 TCPS_HAVERCVDFIN(tp->t_state) == 0) { 1507 #ifndef VBOX_WITH_BSD_REASS1508 TCP_REASS(pData, tp, ti, m, so, tiflags);1509 #else /* VBOX_WITH_BSD_REASS */1510 1318 if (ti->ti_seq == tp->rcv_nxt 1511 1319 && LIST_EMPTY(&tp->t_segq) … … 1525 1333 tiflags |= TF_ACKNOW; 1526 1334 } 1527 #endif /* VBOX_WITH_BSD_REASS */1528 1335 /* 1529 1336 * Note the amount of data that peer has sent into -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r15450 r15453 56 56 tcb.so_next = tcb.so_prev = &tcb; 57 57 tcp_last_so = &tcb; 58 #ifdef VBOX_WITH_BSD_REASS59 58 tcp_reass_maxqlen = 48; 60 59 tcp_reass_maxseg = 256; 61 #endif /* VBOX_WITH_BSD_REASS */62 60 } 63 61 … … 75 73 register struct tcpiphdr *n = &tp->t_template; 76 74 77 #if !defined(VBOX_WITH_BSD_REASS)78 n->ti_next = n->ti_prev = 0;79 n->ti_x1 = 0;80 #else81 75 memset(n->ti_x1, 0, 9); 82 #endif83 76 n->ti_pr = IPPROTO_TCP; 84 77 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); … … 160 153 m->m_len = tlen; 161 154 162 #if !defined(VBOX_WITH_BSD_REASS)163 ti->ti_next = ti->ti_prev = 0;164 ti->ti_x1 = 0;165 #else166 155 memset(ti->ti_x1, 0, 9); 167 #endif168 156 ti->ti_seq = htonl(seq); 169 157 ti->ti_ack = htonl(ack); … … 203 191 204 192 memset((char *) tp, 0, sizeof(struct tcpcb)); 205 #ifndef VBOX_WITH_BSD_REASS206 tp->seg_next = tp->seg_prev = ptr_to_u32(pData, (struct tcpiphdr *)tp);207 #endif /* !VBOX_WITH_BSD_REASS */208 193 tp->t_maxseg = tcp_mssdflt; 209 194 … … 279 264 register struct mbuf *m; 280 265 281 #ifndef VBOX_WITH_BSD_REASS282 DEBUG_CALL("tcp_close");283 DEBUG_ARG("tp = %lx", (long )tp);284 285 /* free the reassembly queue, if any */286 t = u32_to_ptr(pData, tp->seg_next, struct tcpiphdr *);287 while (t != (struct tcpiphdr *)tp)288 {289 t = u32_to_ptr(pData, t->ti_next, struct tcpiphdr *);290 m = REASS_MBUF_GET(u32_to_ptr(pData, t->ti_prev, struct tcpiphdr *));291 remque_32(pData, u32_to_ptr(pData, t->ti_prev, struct tcpiphdr *));292 m_freem(pData, m);293 }294 u32ptr_done(pData, ptr_to_u32(pData, tp), tp);295 #else /* VBOX_WITH_BSD_REASS */296 266 struct tseg_qent *te; 297 267 DEBUG_CALL("tcp_close"); … … 305 275 tcp_reass_qsize--; 306 276 } 307 #endif /* VBOX_WITH_BSD_REASS */308 277 free(tp); 309 278 so->so_tcpcb = 0; … … 972 941 } 973 942 } 974 975 #if SIZEOF_CHAR_P != 4 && !defined(VBOX_WITH_BSD_REASS)976 /**977 * Slow pointer hashing that deals with automatic inserting and collisions.978 */979 uint32_t VBoxU32PtrHashSlow(PNATState pData, void *pv)980 {981 uint32_t i;982 if (pv == NULL)983 i = 0;984 else985 {986 const uint32_t i1 = ((uintptr_t)pv >> 3) % RT_ELEMENTS(pData->apvHash);987 if (pData->apvHash[i1] == pv)988 i = i1;989 else990 {991 /*992 * Try up to 10 times then assume it's an insertion.993 * If we didn't find a free entry by then, try another 100 times.994 * If that fails, give up.995 */996 const uint32_t i2 = ((uintptr_t)pv >> 2) % 7867;997 uint32_t i1stFree = pData->apvHash[i1] ? 0 : i1;998 int cTries = 10;999 int cTries2 = 100;1000 1001 i = i1;1002 for (;;)1003 {1004 /* check if we should give in.*/1005 if (--cTries > 0)1006 {1007 if (i1stFree != 0)1008 {1009 i = i1stFree;1010 pData->apvHash[i] = pv;1011 pData->cpvHashUsed++;1012 if (i != i1)1013 pData->cpvHashCollisions++;1014 pData->cpvHashInserts++;1015 break;1016 }1017 if (!cTries2)1018 {1019 AssertReleaseMsgFailed(("NAT pointer hash error. pv=%p cpvHashUsed=%d cpvHashCollisions=%u\n",1020 pv, pData->cpvHashUsed, pData->cpvHashCollisions));1021 i = 0;1022 break;1023 }1024 cTries = cTries2;1025 cTries2 = 0;1026 }1027 1028 /* advance to the next hash entry and test it. */1029 i = (i + i2) % RT_ELEMENTS(pData->apvHash);1030 while (RT_UNLIKELY(!i))1031 i = (i + i2) % RT_ELEMENTS(pData->apvHash);1032 if (pData->apvHash[i] == pv)1033 break;1034 if (RT_UNLIKELY(!i1stFree && !pData->apvHash[i]))1035 i1stFree = i;1036 }1037 }1038 }1039 return i;1040 }1041 1042 1043 /**1044 * Removes the pointer from the hash table.1045 */1046 void VBoxU32PtrDone(PNATState pData, void *pv, uint32_t iHint)1047 {1048 /* We don't count NULL pointers. */1049 if (pv == NULL)1050 return;1051 pData->cpvHashDone++;1052 1053 /* try the hint */1054 if ( iHint1055 && iHint < RT_ELEMENTS(pData->apvHash)1056 && pData->apvHash[iHint] == pv)1057 {1058 pData->apvHash[iHint] = NULL;1059 pData->cpvHashUsed--;1060 return;1061 }1062 1063 iHint = ((uintptr_t)pv >> 3) % RT_ELEMENTS(pData->apvHash);1064 if (RT_UNLIKELY(pData->apvHash[iHint] != pv))1065 {1066 /*1067 * Try up to 120 times then assert.1068 */1069 const uint32_t i2 = ((uintptr_t)pv >> 2) % 7867;1070 int cTries = 120;1071 for (;;)1072 {1073 /* advance to the next hash entry and test it. */1074 iHint = (iHint + i2) % RT_ELEMENTS(pData->apvHash);1075 while (RT_UNLIKELY(!iHint))1076 iHint = (iHint + i2) % RT_ELEMENTS(pData->apvHash);1077 if (pData->apvHash[iHint] == pv)1078 break;1079 1080 /* check if we should give in.*/1081 if (--cTries > 0)1082 {1083 AssertReleaseMsgFailed(("NAT pointer hash error. pv=%p cpvHashUsed=%u cpvHashCollisions=%u\n",1084 pv, pData->cpvHashUsed, pData->cpvHashCollisions));1085 return;1086 }1087 }1088 }1089 1090 /* found it */1091 pData->apvHash[iHint] = NULL;1092 pData->cpvHashUsed--;1093 }1094 1095 #endif /* SIZEOF_CHAR_P != 4 && !defined(VBOX_WITH_BSD_REASS */ -
trunk/src/VBox/Devices/Network/slirp/tcp_var.h
r15054 r15453 38 38 #define _TCP_VAR_H_ 39 39 40 #ifdef VBOX_WITH_BSD_REASS41 40 #include "queue.h" 42 #endif /* VBOX_WITH_BSD_REASS */43 44 41 #include "tcpip.h" 45 42 #include "tcp_timer.h" 46 43 47 #if SIZEOF_CHAR_P == 448 typedef struct tcpiphdr *tcpiphdrp_32;49 # define u32ptr_done(pData, u32, ptr) do {} while (0)50 # define ptr_to_u32(pData, ptr) (ptr)51 # define u32_to_ptr(pData, u32, type) ((type)(u32))52 #else53 typedef u_int32_t tcpiphdrp_32;54 # include <iprt/types.h>55 # include <iprt/assert.h>56 57 #if defined(VBOX_WITH_BSD_REASS)58 # define u32ptr_done(pData, u32, ptr) do {} while (0)59 # define ptr_to_u32(pData, ptr) (ptr)60 # define u32_to_ptr(pData, u32, type) ((type)(u32))61 #else /* !VBOX_WITH_BSD_REASS */62 # define u32ptr_done(pData, u32, ptr) VBoxU32PtrDone((pData), (ptr), (u32))63 # define ptr_to_u32(pData, ptr) VBoxU32PtrHash((pData), (ptr))64 # define u32_to_ptr(pData, u32, type) ((type)VBoxU32PtrLookup((pData), (u32)))65 #endif /* !VBOX_WITH_BSD_REASS */66 67 #endif68 69 #ifdef VBOX_WITH_BSD_REASS70 44 /* TCP segment queue entry */ 71 45 struct tseg_qent … … 77 51 }; 78 52 LIST_HEAD(tsegqe_head, tseg_qent); 79 #endif80 53 81 54 /* … … 84 57 struct tcpcb 85 58 { 86 #ifndef VBOX_WITH_BSD_REASS87 tcpiphdrp_32 seg_next; /* sequencing queue */88 tcpiphdrp_32 seg_prev;89 #else /* VBOX_WITH_BSD_REASS */90 59 LIST_ENTRY(tcpcb) t_list; 91 60 struct tsegqe_head t_segq; /* segment reassembly queue */ 92 61 int t_segqlen; /* segment reassembly queue length */ 93 #endif /* VBOX_WITH_BSD_REASS */94 62 int16_t t_state; /* state of this connection */ 95 63 int16_t t_timer[TCPT_NTIMERS]; /* tcp timers */ … … 177 145 }; 178 146 179 #ifdef VBOX_WITH_BSD_REASS180 147 LIST_HEAD(tcpcbhead, tcpcb); 181 #endif /* VBOX_WITH_BSD_REASS */182 148 183 149 #define sototcpcb(so) ((so)->so_tcpcb) … … 212 178 #define TCP_REXMTVAL(tp) \ 213 179 (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) 214 215 /* XXX216 * We want to avoid doing m_pullup on incoming packets but that217 * means avoiding dtom on the tcp reassembly code. That in turn means218 * keeping an mbuf pointer in the reassembly queue (since we might219 * have a cluster). As a quick hack, the source & destination220 * port numbers (which are no longer needed once we've located the221 * tcpcb) are overlayed with an mbuf pointer.222 */223 #if SIZEOF_CHAR_P == 4224 typedef struct mbuf *mbufp_32;225 /* VBox change which is too much bother to #ifdef */226 # define REASS_MBUF_SET(ti, p) (*(mbufp_32 *)&((ti)->ti_t)) = (p)227 # define REASS_MBUF_GET(ti) ((struct mbuf *)(*(mbufp_32 *)&((ti)->ti_t)))228 #else229 typedef u_int32_t mbufp_32;230 /* VBox change which is too much bother to #ifdef */231 # define REASS_MBUF_SET(ti, p) (*(mbufp_32 *)&((ti)->ti_t)) = ptr_to_u32(pData, p)232 # define REASS_MBUF_GET(ti) u32_to_ptr(pData, (*(mbufp_32 *)&((ti)->ti_t)), struct mbuf *)233 #endif234 180 235 181 /* … … 293 239 u_long tcps_socachemiss; /* tcp_last_so misses */ 294 240 u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */ 295 #ifdef VBOX_WITH_BSD_REASS 296 u_long tcps_rcvmemdrop; 297 #endif /* VBOX_WITH_BSD_REASS */ 241 u_long tcps_rcvmemdrop; 298 242 }; 299 243 300 301 244 #endif -
trunk/src/VBox/Devices/Network/slirp/udp.c
r15450 r15453 130 130 if (udpcksum && uh->uh_sum) 131 131 { 132 #if !defined(VBOX_WITH_BSD_REASS)133 ((struct ipovly *)ip)->ih_next = 0;134 ((struct ipovly *)ip)->ih_prev = 0;135 ((struct ipovly *)ip)->ih_x1 = 0;136 #else137 132 memset(((struct ipovly *)ip)->ih_x1, 0, 9); 138 #endif139 133 ((struct ipovly *)ip)->ih_len = uh->uh_ulen; 140 134 #if 0 … … 300 294 */ 301 295 ui = mtod(m, struct udpiphdr *); 302 #if !defined(VBOX_WITH_BSD_REASS)303 ui->ui_next = ui->ui_prev = 0;304 ui->ui_x1 = 0;305 #else306 296 memset(ui->ui_x1, 0, 9); 307 #endif308 297 ui->ui_pr = IPPROTO_UDP; 309 298 ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
Note:
See TracChangeset
for help on using the changeset viewer.