Changeset 14275 in vbox
- Timestamp:
- Nov 18, 2008 3:44:28 AM (16 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Makefile.kmk
r14227 r14275 537 537 ifdef VBOX_WITH_BSD_REASS 538 538 Drivers_DEFS = VBOX_WITH_BSD_REASS 539 endif 540 ifdef VBOX_WITH_BSD_TCP_REASS 541 Drivers_DEFS = VBOX_WITH_BSD_TCP_REASS 539 542 endif 540 543 Drivers_INCS := \ -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r14232 r14275 349 349 350 350 /* tcp_input.c */ 351 #ifndef VBOX_WITH_BSD_TCP_REASS 351 352 int tcp_reass _P((PNATState, register struct tcpcb *, register struct tcpiphdr *, struct mbuf *)); 353 #else /* !VBOX_WITH_BSD_TCP_REASS */ 354 int tcp_reass _P((PNATState, struct tcpcb *, struct tcphdr *, int *, struct mbuf *)); 355 #endif /* VBOX_WITH_BSD_TCP_REASS */ 352 356 void tcp_input _P((PNATState, register struct mbuf *, int, struct socket *)); 353 357 void tcp_dooptions _P((PNATState, struct tcpcb *, u_char *, int, struct tcpiphdr *)); -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r14232 r14275 116 116 struct tcpstat_t tcpstat; 117 117 uint32_t tcp_now; 118 #ifdef VBOX_WITH_BSD_TCP_REASS 119 int tcp_reass_qsize; 120 int tcp_reass_maxqlen; 121 int tcp_reass_maxseg; 122 int tcp_reass_overflows; 123 #endif /* VBOX_WITH_BSD_TCP_REASS */ 118 124 /* Stuff from tftp.c */ 119 125 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; … … 237 243 #endif /* VBOX_WITH_BSD_REASS */ 238 244 245 #ifdef VBOX_WITH_BSD_TCP_REASS 246 #define tcp_reass_qsize pData->tcp_reass_qsize 247 #define tcp_reass_maxqlen pData->tcp_reass_maxqlen 248 #define tcp_reass_maxseg pData->tcp_reass_maxseg 249 #define tcp_reass_overflows pData->tcp_reass_overflows 250 #endif /* VBOX_WITH_BSD_TCP_REASS */ 239 251 240 252 #if SIZEOF_CHAR_P != 4 -
trunk/src/VBox/Devices/Network/slirp/tcp_input.c
r14252 r14275 53 53 #define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) 54 54 55 #ifndef VBOX_WITH_BSD_TCP_REASS 55 56 /* 56 57 * Insert segment ti into reassembly queue of tcp with … … 220 221 } 221 222 223 #else /* !VBOX_WITH_BSD_TCP_REASS */ 224 225 #ifndef TCP_ACK_HACK 226 #define DELAY_ACK(tp, ti) \ 227 if (ti->ti_flags & TH_PUSH) \ 228 tp->t_flags |= TF_ACKNOW; \ 229 else \ 230 tp->t_flags |= TF_DELACK; 231 #else /* !TCP_ACK_HACK */ 232 #define DELAY_ACK(tp, ign) \ 233 tp->t_flags |= TF_DELACK; 234 #endif /* TCP_ACK_HACK */ 235 236 237 /* 238 * deps: netinet/tcp_reass.c 239 * tcp_reass_maxqlen = 48 (deafault) 240 * tcp_reass_maxseg = nmbclusters/16 (nmbclusters = 1024 + maxusers * 64 from kern/kern_mbuf.c let's say 256) 241 */ 242 int 243 tcp_reass(PNATState pData, struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) 244 { 245 struct tseg_qent *q; 246 struct tseg_qent *p = NULL; 247 struct tseg_qent *nq; 248 struct tseg_qent *te = NULL; 249 struct socket *so = tp->t_socket; 250 int flags; 251 252 /* 253 * XXX: tcp_reass() is rather inefficient with its data structures 254 * and should be rewritten (see NetBSD for optimizations). While 255 * doing that it should move to its own file tcp_reass.c. 256 */ 257 258 /* 259 * Call with th==NULL after become established to 260 * force pre-ESTABLISHED data up to user socket. 261 */ 262 if (th == NULL) 263 goto present; 264 265 /* 266 * Limit the number of segments in the reassembly queue to prevent 267 * holding on to too many segments (and thus running out of mbufs). 268 * Make sure to let the missing segment through which caused this 269 * queue. Always keep one global queue entry spare to be able to 270 * process the missing segment. 271 */ 272 if (th->th_seq != tp->rcv_nxt && 273 (tcp_reass_qsize + 1 >= tcp_reass_maxseg || 274 tp->t_segqlen >= tcp_reass_maxqlen)) { 275 tcp_reass_overflows++; 276 tcpstat.tcps_rcvmemdrop++; 277 m_freem(pData, m); 278 *tlenp = 0; 279 return (0); 280 } 281 282 /* 283 * Allocate a new queue entry. If we can't, or hit the zone limit 284 * just drop the pkt. 285 */ 286 te = malloc(sizeof(struct tseg_qent)); 287 if (te == NULL) { 288 tcpstat.tcps_rcvmemdrop++; 289 m_freem(pData, m); 290 *tlenp = 0; 291 return (0); 292 } 293 tp->t_segqlen++; 294 tcp_reass_qsize++; 295 296 /* 297 * Find a segment which begins after this one does. 298 */ 299 LIST_FOREACH(q, &tp->t_segq, tqe_q) { 300 if (SEQ_GT(q->tqe_th->th_seq, th->th_seq)) 301 break; 302 p = q; 303 } 304 305 /* 306 * If there is a preceding segment, it may provide some of 307 * our data already. If so, drop the data from the incoming 308 * segment. If it provides all of our data, drop us. 309 */ 310 if (p != NULL) { 311 int i; 312 /* conversion to int (in i) handles seq wraparound */ 313 i = p->tqe_th->th_seq + p->tqe_len - th->th_seq; 314 if (i > 0) { 315 if (i >= *tlenp) { 316 tcpstat.tcps_rcvduppack++; 317 tcpstat.tcps_rcvdupbyte += *tlenp; 318 m_freem(pData, m); 319 free(te); 320 tp->t_segqlen--; 321 tcp_reass_qsize--; 322 /* 323 * Try to present any queued data 324 * at the left window edge to the user. 325 * This is needed after the 3-WHS 326 * completes. 327 */ 328 goto present; /* ??? */ 329 } 330 m_adj(m, i); 331 *tlenp -= i; 332 th->th_seq += i; 333 } 334 } 335 tcpstat.tcps_rcvoopack++; 336 tcpstat.tcps_rcvoobyte += *tlenp; 337 338 /* 339 * While we overlap succeeding segments trim them or, 340 * if they are completely covered, dequeue them. 341 */ 342 while (q) { 343 int i = (th->th_seq + *tlenp) - q->tqe_th->th_seq; 344 if (i <= 0) 345 break; 346 if (i < q->tqe_len) { 347 q->tqe_th->th_seq += i; 348 q->tqe_len -= i; 349 m_adj(q->tqe_m, i); 350 break; 351 } 352 353 nq = LIST_NEXT(q, tqe_q); 354 LIST_REMOVE(q, tqe_q); 355 m_freem(pData, q->tqe_m); 356 free(q); 357 tp->t_segqlen--; 358 tcp_reass_qsize--; 359 q = nq; 360 } 361 362 /* Insert the new segment queue entry into place. */ 363 te->tqe_m = m; 364 te->tqe_th = th; 365 te->tqe_len = *tlenp; 366 367 if (p == NULL) { 368 LIST_INSERT_HEAD(&tp->t_segq, te, tqe_q); 369 } else { 370 LIST_INSERT_AFTER(p, te, tqe_q); 371 } 372 373 present: 374 /* 375 * Present data to user, advancing rcv_nxt through 376 * completed sequence space. 377 */ 378 if (!TCPS_HAVEESTABLISHED(tp->t_state)) 379 return (0); 380 q = LIST_FIRST(&tp->t_segq); 381 if (!q || q->tqe_th->th_seq != tp->rcv_nxt) 382 return (0); 383 do { 384 tp->rcv_nxt += q->tqe_len; 385 flags = q->tqe_th->th_flags & TH_FIN; 386 nq = LIST_NEXT(q, tqe_q); 387 LIST_REMOVE(q, tqe_q); 388 /* XXX: This place should be checked for the same code in 389 * original BSD code for Slirp and current BSD used SS_FCANTRCVMORE 390 */ 391 if (so->so_state & SS_FCANTSENDMORE) 392 m_freem(pData, q->tqe_m); 393 else 394 sbappend(pData, so, q->tqe_m); 395 free(q); 396 tp->t_segqlen--; 397 tcp_reass_qsize--; 398 q = nq; 399 } while (q && q->tqe_th->th_seq == tp->rcv_nxt); 400 return (flags); 401 } 402 #endif /* VBOX_WITH_BSD_TCP_REASS */ 403 222 404 /* 223 405 * TCP input routine, follows pages 65-76 of the … … 545 727 } 546 728 } else if (ti->ti_ack == tp->snd_una && 729 #ifndef VBOX_WITH_BSD_TCP_REASS 547 730 u32_to_ptr(pData, tp->seg_next, struct tcpcb *) == tp && 731 #else /* !VBOX_WITH_BSD_TCP_REASS */ 732 LIST_NEXT(tp, t_list) == tp && 733 #endif /* VBOX_WITH_BSD_TCP_REASS */ 548 734 ti->ti_len <= sbspace(&so->so_rcv)) { 549 735 /* … … 774 960 * } 775 961 */ 962 #ifndef VBOX_WITH_BSD_TCP_REASS 776 963 (void) tcp_reass(pData, tp, (struct tcpiphdr *)0, 777 964 (struct mbuf *)0); 965 #else /* !VBOX_WITH_BSD_TCP_REASS */ 966 (void) tcp_reass(pData, tp, (struct tcphdr *)0, NULL, (struct mbuf *)0); 967 #endif /* VBOX_WITH_BSD_TCP_REASS */ 778 968 /* 779 969 * if we didn't have to retransmit the SYN, … … 1044 1234 * } 1045 1235 */ 1236 #ifndef VBOX_WITH_BSD_TCP_REASS 1046 1237 (void) tcp_reass(pData, tp, (struct tcpiphdr *)0, (struct mbuf *)0); 1238 #else /* !VBOX_WITH_BSD_TCP_REASS */ 1239 (void) tcp_reass(pData, tp, (struct tcpiphdr *)0, (int *)0, (struct mbuf *)0); 1240 #endif /*VBOX_WITH_BSD_TCP_REASS*/ 1047 1241 tp->snd_wl1 = ti->ti_seq - 1; 1048 1242 /* Avoid ack processing; snd_una==ti_ack => dup ack */ … … 1346 1540 if ((ti->ti_len || (tiflags&TH_FIN)) && 1347 1541 TCPS_HAVERCVDFIN(tp->t_state) == 0) { 1542 #ifndef VBOX_WITH_BSD_TCP_REASS 1348 1543 TCP_REASS(pData, tp, ti, m, so, tiflags); 1544 #else /* !VBOX_WITH_BSD_TCP_REASS */ 1545 DELAY_ACK(tp, ti); /* little bit different from BSD declaration see netinet/tcp_input.c */ 1546 tp->rcv_nxt += tlen; 1547 tiflags = ti->ti_t.th_flags & TH_FIN; 1548 tcpstat.tcps_rcvpack++; 1549 tcpstat.tcps_rcvbyte += tlen; 1550 if (so->so_state & SS_FCANTRCVMORE) 1551 m_freem(pData, m); 1552 else 1553 sbappend(pData, so, m); 1554 /* NB: sorwakeup_locked() does an implicit unlock. */ 1555 sorwakeup(so); 1556 #endif /* VBOX_WITH_BSD_TCP_REASS */ 1349 1557 /* 1350 1558 * Note the amount of data that peer has sent into -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r14180 r14275 189 189 190 190 memset((char *) tp, 0, sizeof(struct tcpcb)); 191 #ifndef VBOX_WITH_BSD_TCP_REASS 191 192 tp->seg_next = tp->seg_prev = ptr_to_u32(pData, (struct tcpiphdr *)tp); 193 #else /* !VBOX_WITH_BSD_TCP_REASS */ 194 /*XXX: inject initialization here*/ 195 #endif /* VBOX_WITH_BSD_TCP_REASS */ 192 196 tp->t_maxseg = tcp_mssdflt; 193 197 … … 263 267 DEBUG_ARG("tp = %lx", (long )tp); 264 268 269 #ifndef VBOX_WITH_BSD_TCP_REASS 265 270 /* free the reassembly queue, if any */ 266 271 t = u32_to_ptr(pData, tp->seg_next, struct tcpiphdr *); … … 271 276 m_freem(pData, m); 272 277 } 278 #else /* !VBOX_WITH_BSD_TCP_REASS */ 279 /*XXX: freeing the reassembly queue */ 280 #endif /* VBOX_WITH_BSD_TCP_REASS */ 273 281 /* It's static */ 274 282 /* if (tp->t_template) -
trunk/src/VBox/Devices/Network/slirp/tcp_var.h
r1076 r14275 38 38 #define _TCP_VAR_H_ 39 39 40 #ifdef VBOX_WITH_BSD_TCP_REASS 41 #include <sys/queue.h> 42 #endif /* VBOX_WITH_BSD_TCP_REASS */ 43 40 44 #include "tcpip.h" 41 45 #include "tcp_timer.h" … … 57 61 #endif 58 62 63 #ifdef VBOX_WITH_BSD_TCP_REASS 64 /* TCP segment queue entry */ 65 struct tseg_qent { 66 LIST_ENTRY(tseg_qent) tqe_q; 67 int tqe_len; /* TCP segment data length */ 68 struct tcphdr *tqe_th; /* a pointer to tcp header */ 69 struct mbuf *tqe_m; /* mbuf contains packet */ 70 }; 71 LIST_HEAD(tsegqe_head, tseg_qent); 72 #endif 73 59 74 /* 60 75 * Tcp control block, one per tcp; fields: 61 76 */ 62 77 struct tcpcb { 78 #ifndef VBOX_WITH_BSD_TCP_REASS 63 79 tcpiphdrp_32 seg_next; /* sequencing queue */ 64 80 tcpiphdrp_32 seg_prev; 81 #else /* !VBOX_WITH_BSD_TCP_REASS */ 82 LIST_ENTRY(tcpcb) t_list; 83 struct tsegqe_head t_segq; /* segment reassembly queue */ 84 int t_segqlen; /* segment reassembly queue length */ 85 #endif /* VBOX_WITH_BSD_TCP_REASS */ 65 86 short t_state; /* state of this connection */ 66 87 short t_timer[TCPT_NTIMERS]; /* tcp timers */ … … 148 169 149 170 }; 171 172 #ifdef VBOX_WITH_BSD_TCP_REASS 173 LIST_HEAD(tcpcbhead, tcpcb); 174 #endif /*VBOX_WITH_BSD_TCP_REASS*/ 150 175 151 176 #define sototcpcb(so) ((so)->so_tcpcb) … … 261 286 u_long tcps_socachemiss; /* tcp_last_so misses */ 262 287 u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */ 288 #ifdef VBOX_WITH_BSD_TCP_REASS 289 u_long tcps_rcvmemdrop; 290 #endif /* VBOX_WITH_BSD_TCP_REASS */ 263 291 }; 264 292
Note:
See TracChangeset
for help on using the changeset viewer.