- Timestamp:
- Dec 7, 2008 10:13:12 PM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/debug.h
r14882 r15074 11 11 /* Unused anyway, using VBox Log facility. */ 12 12 #define dfd NULL 13 extern int dostats;14 extern int slirp_debug;15 13 16 14 #define DBG_CALL 0x1 -
trunk/src/VBox/Devices/Network/slirp/tcp_output.c
r14470 r15074 49 49 * names instead of the REAL names 50 50 */ 51 const char * const tcpstates[] = { 52 /* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */ 53 "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD", 54 "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", 55 "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", 51 const char * const tcpstates[] = 52 { 53 /* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */ 54 "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD", 55 "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", 56 "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", 56 57 }; 57 58 58 static const u_char tcp_outflags[TCP_NSTATES] = { 59 TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, 60 TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, 61 TH_FIN|TH_ACK, TH_ACK, TH_ACK, 59 static const u_char tcp_outflags[TCP_NSTATES] = 60 { 61 TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, 62 TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, 63 TH_FIN|TH_ACK, TH_ACK, TH_ACK, 62 64 }; 63 65 … … 71 73 tcp_output(PNATState pData, register struct tcpcb *tp) 72 74 { 73 register struct socket *so = tp->t_socket; 74 register long len, win; 75 int off, flags, error; 76 register struct mbuf *m; 77 register struct tcpiphdr *ti; 78 u_char opt[MAX_TCPOPTLEN]; 79 unsigned optlen, hdrlen; 80 int idle, sendalot; 81 82 DEBUG_CALL("tcp_output"); 83 DEBUG_ARG("tp = %lx", (long )tp); 84 85 /* 86 * Determine length of data that should be transmitted, 87 * and flags that will be used. 88 * If there is some data or critical controls (SYN, RST) 89 * to send, then transmit; otherwise, investigate further. 90 */ 91 idle = (tp->snd_max == tp->snd_una); 92 if (idle && tp->t_idle >= tp->t_rxtcur) 93 /* 94 * We have been idle for "a while" and no acks are 95 * expected to clock out any data we send -- 96 * slow start to get ack "clock" running again. 97 */ 98 tp->snd_cwnd = tp->t_maxseg; 75 register struct socket *so = tp->t_socket; 76 register long len, win; 77 int off, flags, error; 78 register struct mbuf *m; 79 register struct tcpiphdr *ti; 80 u_char opt[MAX_TCPOPTLEN]; 81 unsigned optlen, hdrlen; 82 int idle, sendalot; 83 84 DEBUG_CALL("tcp_output"); 85 DEBUG_ARG("tp = %lx", (long )tp); 86 87 /* 88 * Determine length of data that should be transmitted, 89 * and flags that will be used. 90 * If there is some data or critical controls (SYN, RST) 91 * to send, then transmit; otherwise, investigate further. 92 */ 93 idle = (tp->snd_max == tp->snd_una); 94 if (idle && tp->t_idle >= tp->t_rxtcur) 95 /* 96 * We have been idle for "a while" and no acks are 97 * expected to clock out any data we send -- 98 * slow start to get ack "clock" running again. 99 */ 100 tp->snd_cwnd = tp->t_maxseg; 101 99 102 again: 100 sendalot = 0; 101 off = tp->snd_nxt - tp->snd_una; 102 win = min(tp->snd_wnd, tp->snd_cwnd); 103 104 flags = tcp_outflags[tp->t_state]; 105 106 DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags)); 107 108 /* 109 * If in persist timeout with window of 0, send 1 byte. 110 * Otherwise, if window is small but nonzero 111 * and timer expired, we will send what we can 112 * and go to transmit state. 113 */ 114 if (tp->t_force) { 115 if (win == 0) { 116 /* 117 * If we still have some data to send, then 118 * clear the FIN bit. Usually this would 119 * happen below when it realizes that we 120 * aren't sending all the data. However, 121 * if we have exactly 1 byte of unset data, 122 * then it won't clear the FIN bit below, 123 * and if we are in persist state, we wind 124 * up sending the packet without recording 125 * that we sent the FIN bit. 126 * 127 * We can't just blindly clear the FIN bit, 128 * because if we don't have any more data 129 * to send then the probe will be the FIN 130 * itself. 131 */ 132 if (off < so->so_snd.sb_cc) 133 flags &= ~TH_FIN; 134 win = 1; 135 } else { 136 tp->t_timer[TCPT_PERSIST] = 0; 137 tp->t_rxtshift = 0; 138 } 139 } 140 141 len = min(so->so_snd.sb_cc, win) - off; 142 143 if (len < 0) { 144 /* 145 * If FIN has been sent but not acked, 146 * but we haven't been called to retransmit, 147 * len will be -1. Otherwise, window shrank 148 * after we sent into it. If window shrank to 0, 149 * cancel pending retransmit and pull snd_nxt 150 * back to (closed) window. We will enter persist 151 * state below. If the window didn't close completely, 152 * just wait for an ACK. 153 */ 103 sendalot = 0; 104 off = tp->snd_nxt - tp->snd_una; 105 win = min(tp->snd_wnd, tp->snd_cwnd); 106 107 flags = tcp_outflags[tp->t_state]; 108 109 DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags)); 110 111 /* 112 * If in persist timeout with window of 0, send 1 byte. 113 * Otherwise, if window is small but nonzero 114 * and timer expired, we will send what we can 115 * and go to transmit state. 116 */ 117 if (tp->t_force) 118 { 119 if (win == 0) 120 { 121 /* 122 * If we still have some data to send, then 123 * clear the FIN bit. Usually this would 124 * happen below when it realizes that we 125 * aren't sending all the data. However, 126 * if we have exactly 1 byte of unset data, 127 * then it won't clear the FIN bit below, 128 * and if we are in persist state, we wind 129 * up sending the packet without recording 130 * that we sent the FIN bit. 131 * 132 * We can't just blindly clear the FIN bit, 133 * because if we don't have any more data 134 * to send then the probe will be the FIN 135 * itself. 136 */ 137 if (off < so->so_snd.sb_cc) 138 flags &= ~TH_FIN; 139 win = 1; 140 } 141 else 142 { 143 tp->t_timer[TCPT_PERSIST] = 0; 144 tp->t_rxtshift = 0; 145 } 146 } 147 148 len = min(so->so_snd.sb_cc, win) - off; 149 if (len < 0) 150 { 151 /* 152 * If FIN has been sent but not acked, 153 * but we haven't been called to retransmit, 154 * len will be -1. Otherwise, window shrank 155 * after we sent into it. If window shrank to 0, 156 * cancel pending retransmit and pull snd_nxt 157 * back to (closed) window. We will enter persist 158 * state below. If the window didn't close completely, 159 * just wait for an ACK. 160 */ 161 len = 0; 162 if (win == 0) 163 { 164 tp->t_timer[TCPT_REXMT] = 0; 165 tp->snd_nxt = tp->snd_una; 166 } 167 } 168 if (len > tp->t_maxseg) 169 { 170 len = tp->t_maxseg; 171 sendalot = 1; 172 } 173 if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) 174 flags &= ~TH_FIN; 175 176 win = sbspace(&so->so_rcv); 177 178 /* 179 * Sender silly window avoidance. If connection is idle 180 * and can send all data, a maximum segment, 181 * at least a maximum default-size segment do it, 182 * or are forced, do it; otherwise don't bother. 183 * If peer's buffer is tiny, then send 184 * when window is at least half open. 185 * If retransmitting (possibly after persist timer forced us 186 * to send into a small window), then must resend. 187 */ 188 if (len) 189 { 190 if (len == tp->t_maxseg) 191 goto send; 192 if ((1 || idle || tp->t_flags & TF_NODELAY) && 193 len + off >= so->so_snd.sb_cc) 194 goto send; 195 if (tp->t_force) 196 goto send; 197 if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) 198 goto send; 199 if (SEQ_LT(tp->snd_nxt, tp->snd_max)) 200 goto send; 201 } 202 203 /* 204 * Compare available window to amount of window 205 * known to peer (as advertised window less 206 * next expected input). If the difference is at least two 207 * max size segments, or at least 50% of the maximum possible 208 * window, then want to send a window update to peer. 209 */ 210 if (win > 0) 211 { 212 /* 213 * "adv" is the amount we can increase the window, 214 * taking into account that we are limited by 215 * TCP_MAXWIN << tp->rcv_scale. 216 */ 217 long adv = min(win, 218 (long)TCP_MAXWIN << tp->rcv_scale) - 219 (tp->rcv_adv - tp->rcv_nxt); 220 221 if (adv >= (long) (2 * tp->t_maxseg)) 222 goto send; 223 if (2 * adv >= (long) so->so_rcv.sb_datalen) 224 goto send; 225 } 226 227 /* 228 * Send if we owe peer an ACK. 229 */ 230 if (tp->t_flags & TF_ACKNOW) 231 goto send; 232 if (flags & (TH_SYN|TH_RST)) 233 goto send; 234 if (SEQ_GT(tp->snd_up, tp->snd_una)) 235 goto send; 236 /* 237 * If our state indicates that FIN should be sent 238 * and we have not yet done so, or we're retransmitting the FIN, 239 * then we need to send. 240 */ 241 if ( flags & TH_FIN 242 && ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) 243 goto send; 244 245 /* 246 * TCP window updates are not reliable, rather a polling protocol 247 * using ``persist'' packets is used to insure receipt of window 248 * updates. The three ``states'' for the output side are: 249 * idle not doing retransmits or persists 250 * persisting to move a small or zero window 251 * (re)transmitting and thereby not persisting 252 * 253 * tp->t_timer[TCPT_PERSIST] 254 * is set when we are in persist state. 255 * tp->t_force 256 * is set when we are called to send a persist packet. 257 * tp->t_timer[TCPT_REXMT] 258 * is set when we are retransmitting 259 * The output side is idle when both timers are zero. 260 * 261 * If send window is too small, there is data to transmit, and no 262 * retransmit or persist is pending, then go to persist state. 263 * If nothing happens soon, send when timer expires: 264 * if window is nonzero, transmit what we can, 265 * otherwise force out a byte. 266 */ 267 if ( so->so_snd.sb_cc 268 && tp->t_timer[TCPT_REXMT] == 0 269 && tp->t_timer[TCPT_PERSIST] == 0) 270 { 271 tp->t_rxtshift = 0; 272 tcp_setpersist(tp); 273 } 274 275 /* 276 * No reason to send a segment, just return. 277 */ 278 tcpstat.tcps_didnuttin++; 279 280 return (0); 281 282 send: 283 /* 284 * Before ESTABLISHED, force sending of initial options 285 * unless TCP set not to do any options. 286 * NOTE: we assume that the IP/TCP header plus TCP options 287 * always fit in a single mbuf, leaving room for a maximum 288 * link header, i.e. 289 * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN 290 */ 291 optlen = 0; 292 hdrlen = sizeof (struct tcpiphdr); 293 if (flags & TH_SYN) 294 { 295 tp->snd_nxt = tp->iss; 296 if ((tp->t_flags & TF_NOOPT) == 0) 297 { 298 u_int16_t mss; 299 300 opt[0] = TCPOPT_MAXSEG; 301 opt[1] = 4; 302 mss = htons((u_int16_t) tcp_mss(pData, tp, 0)); 303 memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss)); 304 optlen = 4; 305 306 #if 0 307 if ( (tp->t_flags & TF_REQ_SCALE) 308 && ( (flags & TH_ACK) == 0 309 || (tp->t_flags & TF_RCVD_SCALE))) 310 { 311 *((u_int32_t *) (opt + optlen)) = htonl( TCPOPT_NOP << 24 312 | TCPOPT_WINDOW << 16 313 | TCPOLEN_WINDOW << 8 314 | tp->request_r_scale); 315 optlen += 4; 316 } 317 #endif 318 } 319 } 320 321 /* 322 * Send a timestamp and echo-reply if this is a SYN and our side 323 * wants to use timestamps (TF_REQ_TSTMP is set) or both our side 324 * and our peer have sent timestamps in our SYN's. 325 */ 326 #if 0 327 if ( (tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP 328 && (flags & TH_RST) == 0 329 && ( (flags & (TH_SYN|TH_ACK)) == TH_SYN 330 || (tp->t_flags & TF_RCVD_TSTMP))) 331 { 332 u_int32_t *lp = (u_int32_t *)(opt + optlen); 333 334 /* Form timestamp option as shown in appendix A of RFC 1323. */ 335 *lp++ = htonl(TCPOPT_TSTAMP_HDR); 336 *lp++ = htonl(tcp_now); 337 *lp = htonl(tp->ts_recent); 338 optlen += TCPOLEN_TSTAMP_APPA; 339 } 340 #endif 341 hdrlen += optlen; 342 343 /* 344 * Adjust data length if insertion of options will 345 * bump the packet length beyond the t_maxseg length. 346 */ 347 if (len > tp->t_maxseg - optlen) 348 { 349 len = tp->t_maxseg - optlen; 350 sendalot = 1; 351 } 352 353 /* 354 * Grab a header mbuf, attaching a copy of data to 355 * be transmitted, and initialize the header from 356 * the template for sends on this connection. 357 */ 358 if (len) 359 { 360 if (tp->t_force && len == 1) 361 tcpstat.tcps_sndprobe++; 362 else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) 363 { 364 tcpstat.tcps_sndrexmitpack++; 365 tcpstat.tcps_sndrexmitbyte += len; 366 } 367 else 368 { 369 tcpstat.tcps_sndpack++; 370 tcpstat.tcps_sndbyte += len; 371 } 372 373 m = m_get(pData); 374 if (m == NULL) 375 { 376 /* error = ENOBUFS; */ 377 error = 1; 378 goto out; 379 } 380 m->m_data += if_maxlinkhdr; 381 m->m_len = hdrlen; 382 383 /* 384 * This will always succeed, since we make sure our mbufs 385 * are big enough to hold one MSS packet + header + ... etc. 386 */ 387 #if 0 388 if (len <= MHLEN - hdrlen - max_linkhdr) 389 { 390 #endif 391 sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen); 392 m->m_len += len; 393 #if 0 394 } 395 else 396 { 397 m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); 398 if (m->m_next == 0) 154 399 len = 0; 155 if (win == 0) { 156 tp->t_timer[TCPT_REXMT] = 0; 157 tp->snd_nxt = tp->snd_una; 158 } 159 } 160 161 if (len > tp->t_maxseg) { 162 len = tp->t_maxseg; 163 sendalot = 1; 164 } 165 if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) 166 flags &= ~TH_FIN; 167 168 win = sbspace(&so->so_rcv); 169 170 /* 171 * Sender silly window avoidance. If connection is idle 172 * and can send all data, a maximum segment, 173 * at least a maximum default-size segment do it, 174 * or are forced, do it; otherwise don't bother. 175 * If peer's buffer is tiny, then send 176 * when window is at least half open. 177 * If retransmitting (possibly after persist timer forced us 178 * to send into a small window), then must resend. 179 */ 180 if (len) { 181 if (len == tp->t_maxseg) 182 goto send; 183 if ((1 || idle || tp->t_flags & TF_NODELAY) && 184 len + off >= so->so_snd.sb_cc) 185 goto send; 186 if (tp->t_force) 187 goto send; 188 if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) 189 goto send; 190 if (SEQ_LT(tp->snd_nxt, tp->snd_max)) 191 goto send; 192 } 193 194 /* 195 * Compare available window to amount of window 196 * known to peer (as advertised window less 197 * next expected input). If the difference is at least two 198 * max size segments, or at least 50% of the maximum possible 199 * window, then want to send a window update to peer. 200 */ 201 if (win > 0) { 202 /* 203 * "adv" is the amount we can increase the window, 204 * taking into account that we are limited by 205 * TCP_MAXWIN << tp->rcv_scale. 206 */ 207 long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - 208 (tp->rcv_adv - tp->rcv_nxt); 209 210 if (adv >= (long) (2 * tp->t_maxseg)) 211 goto send; 212 if (2 * adv >= (long) so->so_rcv.sb_datalen) 213 goto send; 214 } 215 216 /* 217 * Send if we owe peer an ACK. 218 */ 400 } 401 #endif 402 /* 403 * If we're sending everything we've got, set PUSH. 404 * (This will keep happy those implementations which only 405 * give data to the user when a buffer fills or 406 * a PUSH comes in.) 407 */ 408 if (off + len == so->so_snd.sb_cc) 409 flags |= TH_PUSH; 410 } 411 else 412 { 219 413 if (tp->t_flags & TF_ACKNOW) 220 goto send; 221 if (flags & (TH_SYN|TH_RST)) 222 goto send; 223 if (SEQ_GT(tp->snd_up, tp->snd_una)) 224 goto send; 225 /* 226 * If our state indicates that FIN should be sent 227 * and we have not yet done so, or we're retransmitting the FIN, 228 * then we need to send. 229 */ 230 if (flags & TH_FIN && 231 ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) 232 goto send; 233 234 /* 235 * TCP window updates are not reliable, rather a polling protocol 236 * using ``persist'' packets is used to insure receipt of window 237 * updates. The three ``states'' for the output side are: 238 * idle not doing retransmits or persists 239 * persisting to move a small or zero window 240 * (re)transmitting and thereby not persisting 241 * 242 * tp->t_timer[TCPT_PERSIST] 243 * is set when we are in persist state. 244 * tp->t_force 245 * is set when we are called to send a persist packet. 246 * tp->t_timer[TCPT_REXMT] 247 * is set when we are retransmitting 248 * The output side is idle when both timers are zero. 249 * 250 * If send window is too small, there is data to transmit, and no 251 * retransmit or persist is pending, then go to persist state. 252 * If nothing happens soon, send when timer expires: 253 * if window is nonzero, transmit what we can, 254 * otherwise force out a byte. 255 */ 256 if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 && 257 tp->t_timer[TCPT_PERSIST] == 0) { 414 tcpstat.tcps_sndacks++; 415 else if (flags & (TH_SYN|TH_FIN|TH_RST)) 416 tcpstat.tcps_sndctrl++; 417 else if (SEQ_GT(tp->snd_up, tp->snd_una)) 418 tcpstat.tcps_sndurg++; 419 else 420 tcpstat.tcps_sndwinup++; 421 422 m = m_get(pData); 423 if (m == NULL) 424 { 425 /* error = ENOBUFS; */ 426 error = 1; 427 goto out; 428 } 429 m->m_data += if_maxlinkhdr; 430 m->m_len = hdrlen; 431 } 432 433 ti = mtod(m, struct tcpiphdr *); 434 435 memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr)); 436 437 /* 438 * Fill in fields, remembering maximum advertised 439 * window for use in delaying messages about window sizes. 440 * If resending a FIN, be sure not to use a new sequence number. 441 */ 442 if ( flags & TH_FIN 443 && tp->t_flags & TF_SENTFIN 444 && tp->snd_nxt == tp->snd_max) 445 tp->snd_nxt--; 446 /* 447 * If we are doing retransmissions, then snd_nxt will 448 * not reflect the first unsent octet. For ACK only 449 * packets, we do not want the sequence number of the 450 * retransmitted packet, we want the sequence number 451 * of the next unsent octet. So, if there is no data 452 * (and no SYN or FIN), use snd_max instead of snd_nxt 453 * when filling in ti_seq. But if we are in persist 454 * state, snd_max might reflect one byte beyond the 455 * right edge of the window, so use snd_nxt in that 456 * case, since we know we aren't doing a retransmission. 457 * (retransmit and persist are mutually exclusive...) 458 */ 459 if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST]) 460 ti->ti_seq = htonl(tp->snd_nxt); 461 else 462 ti->ti_seq = htonl(tp->snd_max); 463 ti->ti_ack = htonl(tp->rcv_nxt); 464 if (optlen) 465 { 466 memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen); 467 ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; 468 } 469 ti->ti_flags = flags; 470 /* 471 * Calculate receive window. Don't shrink window, 472 * but avoid silly window syndrome. 473 */ 474 if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) 475 win = 0; 476 if (win > (long)TCP_MAXWIN << tp->rcv_scale) 477 win = (long)TCP_MAXWIN << tp->rcv_scale; 478 if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) 479 win = (long)(tp->rcv_adv - tp->rcv_nxt); 480 ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); 481 482 #if 0 483 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) 484 { 485 ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt)); 486 #else 487 if (SEQ_GT(tp->snd_up, tp->snd_una)) 488 { 489 ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq))); 490 #endif 491 ti->ti_flags |= TH_URG; 492 } 493 else 494 /* 495 * If no urgent pointer to send, then we pull 496 * the urgent pointer to the left edge of the send window 497 * so that it doesn't drift into the send window on sequence 498 * number wraparound. 499 */ 500 tp->snd_up = tp->snd_una; /* drag it along */ 501 502 /* 503 * Put TCP length in extended header, and then 504 * checksum extended header and data. 505 */ 506 if (len + optlen) 507 ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) 508 + optlen + len)); 509 ti->ti_sum = cksum(m, (int)(hdrlen + len)); 510 511 /* 512 * In transmit state, time the transmission and arrange for 513 * the retransmit. In persist state, just set snd_max. 514 */ 515 if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) 516 { 517 tcp_seq startseq = tp->snd_nxt; 518 519 /* 520 * Advance snd_nxt over sequence space of this segment. 521 */ 522 if (flags & (TH_SYN|TH_FIN)) 523 { 524 if (flags & TH_SYN) 525 tp->snd_nxt++; 526 if (flags & TH_FIN) 527 { 528 tp->snd_nxt++; 529 tp->t_flags |= TF_SENTFIN; 530 } 531 } 532 tp->snd_nxt += len; 533 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) 534 { 535 tp->snd_max = tp->snd_nxt; 536 /* 537 * Time this transmission if not a retransmission and 538 * not currently timing anything. 539 */ 540 if (tp->t_rtt == 0) 541 { 542 tp->t_rtt = 1; 543 tp->t_rtseq = startseq; 544 tcpstat.tcps_segstimed++; 545 } 546 } 547 548 /* 549 * Set retransmit timer if not currently set, 550 * and not doing an ack or a keep-alive probe. 551 * Initial value for retransmit timer is smoothed 552 * round-trip time + 2 * round-trip time variance. 553 * Initialize shift counter which is used for backoff 554 * of retransmit time. 555 */ 556 if ( tp->t_timer[TCPT_REXMT] == 0 557 && tp->snd_nxt != tp->snd_una) 558 { 559 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; 560 if (tp->t_timer[TCPT_PERSIST]) 561 { 562 tp->t_timer[TCPT_PERSIST] = 0; 258 563 tp->t_rxtshift = 0; 259 tcp_setpersist(tp); 260 } 261 262 /* 263 * No reason to send a segment, just return. 264 */ 265 tcpstat.tcps_didnuttin++; 266 267 return (0); 268 269 send: 270 /* 271 * Before ESTABLISHED, force sending of initial options 272 * unless TCP set not to do any options. 273 * NOTE: we assume that the IP/TCP header plus TCP options 274 * always fit in a single mbuf, leaving room for a maximum 275 * link header, i.e. 276 * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN 277 */ 278 optlen = 0; 279 hdrlen = sizeof (struct tcpiphdr); 280 if (flags & TH_SYN) { 281 tp->snd_nxt = tp->iss; 282 if ((tp->t_flags & TF_NOOPT) == 0) { 283 u_int16_t mss; 284 285 opt[0] = TCPOPT_MAXSEG; 286 opt[1] = 4; 287 mss = htons((u_int16_t) tcp_mss(pData, tp, 0)); 288 memcpy((caddr_t)(opt + 2), (caddr_t)&mss, sizeof(mss)); 289 optlen = 4; 290 291 /* if ((tp->t_flags & TF_REQ_SCALE) && 292 * ((flags & TH_ACK) == 0 || 293 * (tp->t_flags & TF_RCVD_SCALE))) { 294 * *((u_int32_t *) (opt + optlen)) = htonl( 295 * TCPOPT_NOP << 24 | 296 * TCPOPT_WINDOW << 16 | 297 * TCPOLEN_WINDOW << 8 | 298 * tp->request_r_scale); 299 * optlen += 4; 300 * } 301 */ 302 } 303 } 304 305 /* 306 * Send a timestamp and echo-reply if this is a SYN and our side 307 * wants to use timestamps (TF_REQ_TSTMP is set) or both our side 308 * and our peer have sent timestamps in our SYN's. 309 */ 310 /* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && 311 * (flags & TH_RST) == 0 && 312 * ((flags & (TH_SYN|TH_ACK)) == TH_SYN || 313 * (tp->t_flags & TF_RCVD_TSTMP))) { 314 * u_int32_t *lp = (u_int32_t *)(opt + optlen); 315 * 316 * / * Form timestamp option as shown in appendix A of RFC 1323. * / 317 * *lp++ = htonl(TCPOPT_TSTAMP_HDR); 318 * *lp++ = htonl(tcp_now); 319 * *lp = htonl(tp->ts_recent); 320 * optlen += TCPOLEN_TSTAMP_APPA; 321 * } 322 */ 323 hdrlen += optlen; 324 325 /* 326 * Adjust data length if insertion of options will 327 * bump the packet length beyond the t_maxseg length. 328 */ 329 if (len > tp->t_maxseg - optlen) { 330 len = tp->t_maxseg - optlen; 331 sendalot = 1; 332 } 333 334 /* 335 * Grab a header mbuf, attaching a copy of data to 336 * be transmitted, and initialize the header from 337 * the template for sends on this connection. 338 */ 339 if (len) { 340 if (tp->t_force && len == 1) 341 tcpstat.tcps_sndprobe++; 342 else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { 343 tcpstat.tcps_sndrexmitpack++; 344 tcpstat.tcps_sndrexmitbyte += len; 345 } else { 346 tcpstat.tcps_sndpack++; 347 tcpstat.tcps_sndbyte += len; 348 } 349 350 m = m_get(pData); 351 if (m == NULL) { 352 /* error = ENOBUFS; */ 353 error = 1; 354 goto out; 355 } 356 m->m_data += if_maxlinkhdr; 357 m->m_len = hdrlen; 358 359 /* 360 * This will always succeed, since we make sure our mbufs 361 * are big enough to hold one MSS packet + header + ... etc. 362 */ 363 /* if (len <= MHLEN - hdrlen - max_linkhdr) { */ 364 365 sbcopy(&so->so_snd, off, (int) len, mtod(m, caddr_t) + hdrlen); 366 m->m_len += len; 367 368 /* } else { 369 * m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); 370 * if (m->m_next == 0) 371 * len = 0; 372 * } 373 */ 374 /* 375 * If we're sending everything we've got, set PUSH. 376 * (This will keep happy those implementations which only 377 * give data to the user when a buffer fills or 378 * a PUSH comes in.) 379 */ 380 if (off + len == so->so_snd.sb_cc) 381 flags |= TH_PUSH; 382 } else { 383 if (tp->t_flags & TF_ACKNOW) 384 tcpstat.tcps_sndacks++; 385 else if (flags & (TH_SYN|TH_FIN|TH_RST)) 386 tcpstat.tcps_sndctrl++; 387 else if (SEQ_GT(tp->snd_up, tp->snd_una)) 388 tcpstat.tcps_sndurg++; 389 else 390 tcpstat.tcps_sndwinup++; 391 392 m = m_get(pData); 393 if (m == NULL) { 394 /* error = ENOBUFS; */ 395 error = 1; 396 goto out; 397 } 398 m->m_data += if_maxlinkhdr; 399 m->m_len = hdrlen; 400 } 401 402 ti = mtod(m, struct tcpiphdr *); 403 404 memcpy((caddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr)); 405 406 /* 407 * Fill in fields, remembering maximum advertised 408 * window for use in delaying messages about window sizes. 409 * If resending a FIN, be sure not to use a new sequence number. 410 */ 411 if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && 412 tp->snd_nxt == tp->snd_max) 413 tp->snd_nxt--; 414 /* 415 * If we are doing retransmissions, then snd_nxt will 416 * not reflect the first unsent octet. For ACK only 417 * packets, we do not want the sequence number of the 418 * retransmitted packet, we want the sequence number 419 * of the next unsent octet. So, if there is no data 420 * (and no SYN or FIN), use snd_max instead of snd_nxt 421 * when filling in ti_seq. But if we are in persist 422 * state, snd_max might reflect one byte beyond the 423 * right edge of the window, so use snd_nxt in that 424 * case, since we know we aren't doing a retransmission. 425 * (retransmit and persist are mutually exclusive...) 426 */ 427 if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST]) 428 ti->ti_seq = htonl(tp->snd_nxt); 429 else 430 ti->ti_seq = htonl(tp->snd_max); 431 ti->ti_ack = htonl(tp->rcv_nxt); 432 if (optlen) { 433 memcpy((caddr_t)(ti + 1), (caddr_t)opt, optlen); 434 ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; 435 } 436 ti->ti_flags = flags; 437 /* 438 * Calculate receive window. Don't shrink window, 439 * but avoid silly window syndrome. 440 */ 441 if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) 442 win = 0; 443 if (win > (long)TCP_MAXWIN << tp->rcv_scale) 444 win = (long)TCP_MAXWIN << tp->rcv_scale; 445 if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) 446 win = (long)(tp->rcv_adv - tp->rcv_nxt); 447 ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); 448 449 if (SEQ_GT(tp->snd_up, tp->snd_una)) { 450 ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq))); 451 #ifdef notdef 452 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { 453 ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt)); 454 #endif 455 ti->ti_flags |= TH_URG; 456 } else 457 /* 458 * If no urgent pointer to send, then we pull 459 * the urgent pointer to the left edge of the send window 460 * so that it doesn't drift into the send window on sequence 461 * number wraparound. 462 */ 463 tp->snd_up = tp->snd_una; /* drag it along */ 464 465 /* 466 * Put TCP length in extended header, and then 467 * checksum extended header and data. 468 */ 469 if (len + optlen) 470 ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + 471 optlen + len)); 472 ti->ti_sum = cksum(m, (int)(hdrlen + len)); 473 474 /* 475 * In transmit state, time the transmission and arrange for 476 * the retransmit. In persist state, just set snd_max. 477 */ 478 if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) { 479 tcp_seq startseq = tp->snd_nxt; 480 481 /* 482 * Advance snd_nxt over sequence space of this segment. 483 */ 484 if (flags & (TH_SYN|TH_FIN)) { 485 if (flags & TH_SYN) 486 tp->snd_nxt++; 487 if (flags & TH_FIN) { 488 tp->snd_nxt++; 489 tp->t_flags |= TF_SENTFIN; 490 } 491 } 492 tp->snd_nxt += len; 493 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { 494 tp->snd_max = tp->snd_nxt; 495 /* 496 * Time this transmission if not a retransmission and 497 * not currently timing anything. 498 */ 499 if (tp->t_rtt == 0) { 500 tp->t_rtt = 1; 501 tp->t_rtseq = startseq; 502 tcpstat.tcps_segstimed++; 503 } 504 } 505 506 /* 507 * Set retransmit timer if not currently set, 508 * and not doing an ack or a keep-alive probe. 509 * Initial value for retransmit timer is smoothed 510 * round-trip time + 2 * round-trip time variance. 511 * Initialize shift counter which is used for backoff 512 * of retransmit time. 513 */ 514 if (tp->t_timer[TCPT_REXMT] == 0 && 515 tp->snd_nxt != tp->snd_una) { 516 tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; 517 if (tp->t_timer[TCPT_PERSIST]) { 518 tp->t_timer[TCPT_PERSIST] = 0; 519 tp->t_rxtshift = 0; 520 } 521 } 522 } else 523 if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) 524 tp->snd_max = tp->snd_nxt + len; 525 526 /* 527 * Fill in IP length and desired time to live and 528 * send to IP level. There should be a better way 529 * to handle ttl and tos; we could keep them in 530 * the template, but need a way to checksum without them. 531 */ 532 m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ 533 534 { 535 564 } 565 } 566 } 567 else 568 if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) 569 tp->snd_max = tp->snd_nxt + len; 570 571 /* 572 * Fill in IP length and desired time to live and 573 * send to IP level. There should be a better way 574 * to handle ttl and tos; we could keep them in 575 * the template, but need a way to checksum without them. 576 */ 577 m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ 578 579 { 536 580 ((struct ip *)ti)->ip_len = m->m_len; 537 538 581 ((struct ip *)ti)->ip_ttl = ip_defttl; 539 582 ((struct ip *)ti)->ip_tos = so->so_iptos; 540 583 541 /* #if BSD >= 43 */584 /* #if BSD >= 43 */ 542 585 /* Don't do IP options... */ 543 /* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, 544 * so->so_options & SO_DONTROUTE, 0); 545 */ 586 #if 0 587 error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, 588 so->so_options & SO_DONTROUTE, 0); 589 #endif 546 590 error = ip_output(pData, so, m); 547 591 548 /* #else 549 * error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, 550 * so->so_options & SO_DONTROUTE); 551 * #endif 552 */ 553 } 554 if (error) { 592 #if 0 593 /* #else */ 594 error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, 595 so->so_options & SO_DONTROUTE); 596 /* #endif */ 597 #endif 598 } 599 if (error) 600 { 555 601 out: 556 /* if (error == ENOBUFS) { 557 * tcp_quench(tp->t_inpcb, 0); 558 * return (0); 559 * } 560 */ 561 /* if ((error == EHOSTUNREACH || error == ENETDOWN) 562 * && TCPS_HAVERCVDSYN(tp->t_state)) { 563 * tp->t_softerror = error; 564 * return (0); 565 * } 566 */ 567 return (error); 568 } 569 tcpstat.tcps_sndtotal++; 570 571 /* 572 * Data sent (as far as we can tell). 573 * If this advertises a larger window than any other segment, 574 * then remember the size of the advertised window. 575 * Any pending ACK has now been sent. 576 */ 577 if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) 578 tp->rcv_adv = tp->rcv_nxt + win; 579 tp->last_ack_sent = tp->rcv_nxt; 580 tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); 581 if (sendalot) 582 goto again; 583 584 return (0); 602 #if 0 603 if (error == ENOBUFS) 604 { 605 tcp_quench(tp->t_inpcb, 0); 606 return (0); 607 } 608 609 if ( ( error == EHOSTUNREACH 610 || error == ENETDOWN) 611 && TCPS_HAVERCVDSYN(tp->t_state)) 612 { 613 tp->t_softerror = error; 614 return (0); 615 } 616 #endif 617 return (error); 618 } 619 tcpstat.tcps_sndtotal++; 620 621 /* 622 * Data sent (as far as we can tell). 623 * If this advertises a larger window than any other segment, 624 * then remember the size of the advertised window. 625 * Any pending ACK has now been sent. 626 */ 627 if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) 628 tp->rcv_adv = tp->rcv_nxt + win; 629 tp->last_ack_sent = tp->rcv_nxt; 630 tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); 631 if (sendalot) 632 goto again; 633 634 return (0); 585 635 } 586 636 587 637 void 588 tcp_setpersist(tp) 589 register struct tcpcb *tp; 638 tcp_setpersist(struct tcpcb *tp) 590 639 { 591 640 int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; 592 641 593 /* if (tp->t_timer[TCPT_REXMT]) 594 * panic("tcp_output REXMT"); 595 */ 596 /* 597 * Start/restart persistence timer. 598 */ 599 TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], 600 t * tcp_backoff[tp->t_rxtshift], 601 TCPTV_PERSMIN, TCPTV_PERSMAX); 602 if (tp->t_rxtshift < TCP_MAXRXTSHIFT) 603 tp->t_rxtshift++; 642 #if 0 643 if (tp->t_timer[TCPT_REXMT]) 644 panic("tcp_output REXMT"); 645 #endif 646 /* 647 * Start/restart persistence timer. 648 */ 649 TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], 650 t * tcp_backoff[tp->t_rxtshift], 651 TCPTV_PERSMIN, TCPTV_PERSMAX); 652 if (tp->t_rxtshift < TCP_MAXRXTSHIFT) 653 tp->t_rxtshift++; 604 654 } -
trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
r14638 r15074 53 53 tcp_init(PNATState pData) 54 54 { 55 56 57 55 tcp_iss = 1; /* wrong */ 56 tcb.so_next = tcb.so_prev = &tcb; 57 tcp_last_so = &tcb; 58 58 #ifdef VBOX_WITH_BSD_REASS 59 60 59 tcp_reass_maxqlen = 48; 60 tcp_reass_maxseg = 256; 61 61 #endif /* VBOX_WITH_BSD_REASS */ 62 62 } … … 70 70 /* struct tcpiphdr * */ 71 71 void 72 tcp_template(tp) 73 struct tcpcb *tp; 74 { 75 struct socket *so = tp->t_socket; 76 register struct tcpiphdr *n = &tp->t_template; 72 tcp_template(struct tcpcb *tp) 73 { 74 struct socket *so = tp->t_socket; 75 register struct tcpiphdr *n = &tp->t_template; 77 76 78 77 #if !defined(VBOX_WITH_BSD_REASS) 79 80 78 n->ti_next = n->ti_prev = 0; 79 n->ti_x1 = 0; 81 80 #else 82 81 memset(n->ti_x1, 0, 9); 83 82 #endif 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 83 n->ti_pr = IPPROTO_TCP; 84 n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); 85 n->ti_src = so->so_faddr; 86 n->ti_dst = so->so_laddr; 87 n->ti_sport = so->so_fport; 88 n->ti_dport = so->so_lport; 89 90 n->ti_seq = 0; 91 n->ti_ack = 0; 92 n->ti_x2 = 0; 93 n->ti_off = 5; 94 n->ti_flags = 0; 95 n->ti_win = 0; 96 n->ti_sum = 0; 97 n->ti_urp = 0; 99 98 } 100 99 … … 115 114 tcp_respond(PNATState pData, struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags) 116 115 { 117 register int tlen; 118 int win = 0; 119 120 DEBUG_CALL("tcp_respond"); 121 DEBUG_ARG("tp = %lx", (long)tp); 122 DEBUG_ARG("ti = %lx", (long)ti); 123 DEBUG_ARG("m = %lx", (long)m); 124 DEBUG_ARG("ack = %u", ack); 125 DEBUG_ARG("seq = %u", seq); 126 DEBUG_ARG("flags = %x", flags); 127 128 if (tp) 129 win = sbspace(&tp->t_socket->so_rcv); 130 if (m == 0) { 131 if ((m = m_get(pData)) == NULL) 132 return; 116 register int tlen; 117 int win = 0; 118 119 DEBUG_CALL("tcp_respond"); 120 DEBUG_ARG("tp = %lx", (long)tp); 121 DEBUG_ARG("ti = %lx", (long)ti); 122 DEBUG_ARG("m = %lx", (long)m); 123 DEBUG_ARG("ack = %u", ack); 124 DEBUG_ARG("seq = %u", seq); 125 DEBUG_ARG("flags = %x", flags); 126 127 if (tp) 128 win = sbspace(&tp->t_socket->so_rcv); 129 if (m == 0) 130 { 131 if ((m = m_get(pData)) == NULL) 132 return; 133 133 #ifdef TCP_COMPAT_42 134 134 tlen = 1; 135 135 #else 136 136 tlen = 0; 137 137 #endif 138 m->m_data += if_maxlinkhdr; 139 *mtod(m, struct tcpiphdr *) = *ti; 140 ti = mtod(m, struct tcpiphdr *); 141 flags = TH_ACK; 142 } else { 143 /* 144 * ti points into m so the next line is just making 145 * the mbuf point to ti 146 */ 147 m->m_data = (caddr_t)ti; 148 149 m->m_len = sizeof (struct tcpiphdr); 150 tlen = 0; 138 m->m_data += if_maxlinkhdr; 139 *mtod(m, struct tcpiphdr *) = *ti; 140 ti = mtod(m, struct tcpiphdr *); 141 flags = TH_ACK; 142 } 143 else 144 { 145 /* 146 * ti points into m so the next line is just making 147 * the mbuf point to ti 148 */ 149 m->m_data = (caddr_t)ti; 150 151 m->m_len = sizeof (struct tcpiphdr); 152 tlen = 0; 151 153 #define xchg(a,b,type) { type t; t=a; a=b; b=t; } 152 153 154 xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); 155 xchg(ti->ti_dport, ti->ti_sport, u_int16_t); 154 156 #undef xchg 155 156 157 158 157 } 158 ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); 159 tlen += sizeof (struct tcpiphdr); 160 m->m_len = tlen; 159 161 160 162 #if !defined(VBOX_WITH_BSD_REASS) 161 162 163 ti->ti_next = ti->ti_prev = 0; 164 ti->ti_x1 = 0; 163 165 #else 164 166 memset(ti->ti_x1, 0, 9); 165 167 #endif 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 168 ti->ti_seq = htonl(seq); 169 ti->ti_ack = htonl(ack); 170 ti->ti_x2 = 0; 171 ti->ti_off = sizeof (struct tcphdr) >> 2; 172 ti->ti_flags = flags; 173 if (tp) 174 ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); 175 else 176 ti->ti_win = htons((u_int16_t)win); 177 ti->ti_urp = 0; 178 ti->ti_sum = 0; 179 ti->ti_sum = cksum(m, tlen); 180 ((struct ip *)ti)->ip_len = tlen; 181 182 if(flags & TH_RST) 183 ((struct ip *)ti)->ip_ttl = MAXTTL; 184 else 185 ((struct ip *)ti)->ip_ttl = ip_defttl; 186 187 (void) ip_output(pData, (struct socket *)0, m); 186 188 } 187 189 … … 194 196 tcp_newtcpcb(PNATState pData, struct socket *so) 195 197 { 196 197 198 199 200 201 202 198 register struct tcpcb *tp; 199 200 tp = (struct tcpcb *)malloc(sizeof(*tp)); 201 if (tp == NULL) 202 return ((struct tcpcb *)0); 203 204 memset((char *) tp, 0, sizeof(struct tcpcb)); 203 205 #ifndef VBOX_WITH_BSD_REASS 204 206 tp->seg_next = tp->seg_prev = ptr_to_u32(pData, (struct tcpiphdr *)tp); 205 207 #endif /* !VBOX_WITH_BSD_REASS */ 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1,222 TCPTV_MIN, TCPTV_REXMTMAX);223 224 225 226 227 228 229 230 208 tp->t_maxseg = tcp_mssdflt; 209 210 tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; 211 tp->t_socket = so; 212 213 /* 214 * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no 215 * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives 216 * reasonable initial retransmit time. 217 */ 218 tp->t_srtt = TCPTV_SRTTBASE; 219 tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2; 220 tp->t_rttmin = TCPTV_MIN; 221 222 TCPT_RANGESET(tp->t_rxtcur, 223 ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, 224 TCPTV_MIN, TCPTV_REXMTMAX); 225 226 tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; 227 tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; 228 tp->t_state = TCPS_CLOSED; 229 230 so->so_tcpcb = tp; 231 232 return (tp); 231 233 } 232 234 … … 243 245 { 244 246 */ 245 246 DEBUG_CALL("tcp_drop"); 247 DEBUG_ARG("tp = %lx", (long)tp); 248 DEBUG_ARG("errno = %d", errno); 249 250 if (TCPS_HAVERCVDSYN(tp->t_state)) { 251 tp->t_state = TCPS_CLOSED; 252 (void) tcp_output(pData, tp); 253 tcpstat.tcps_drops++; 254 } else 255 tcpstat.tcps_conndrops++; 256 /* if (errno == ETIMEDOUT && tp->t_softerror) 257 * errno = tp->t_softerror; 258 */ 259 /* so->so_error = errno; */ 260 return (tcp_close(pData, tp)); 247 DEBUG_CALL("tcp_drop"); 248 DEBUG_ARG("tp = %lx", (long)tp); 249 DEBUG_ARG("errno = %d", errno); 250 251 if (TCPS_HAVERCVDSYN(tp->t_state)) 252 { 253 tp->t_state = TCPS_CLOSED; 254 (void) tcp_output(pData, tp); 255 tcpstat.tcps_drops++; 256 } 257 else 258 tcpstat.tcps_conndrops++; 259 #if 0 260 if (errno == ETIMEDOUT && tp->t_softerror) 261 errno = tp->t_softerror; 262 263 so->so_error = errno; 264 #endif 265 return (tcp_close(pData, tp)); 261 266 } 262 267 … … 270 275 tcp_close(PNATState pData, register struct tcpcb *tp) 271 276 { 272 273 274 277 register struct tcpiphdr *t; 278 struct socket *so = tp->t_socket; 279 register struct mbuf *m; 275 280 276 281 #ifndef VBOX_WITH_BSD_REASS 277 DEBUG_CALL("tcp_close"); 278 DEBUG_ARG("tp = %lx", (long )tp); 279 280 /* free the reassembly queue, if any */ 281 t = u32_to_ptr(pData, tp->seg_next, struct tcpiphdr *); 282 while (t != (struct tcpiphdr *)tp) { 283 t = u32_to_ptr(pData, t->ti_next, struct tcpiphdr *); 284 m = REASS_MBUF_GET(u32_to_ptr(pData, t->ti_prev, struct tcpiphdr *)); 285 remque_32(pData, u32_to_ptr(pData, t->ti_prev, struct tcpiphdr *)); 286 m_freem(pData, m); 287 } 288 /* It's static */ 289 /* if (tp->t_template) 290 * (void) m_free(dtom(tp->t_template)); 291 */ 292 /* free(tp, M_PCB); */ 293 u32ptr_done(pData, ptr_to_u32(pData, tp), tp); 282 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 /* It's static */ 295 #if 0 296 if (tp->t_template) 297 (void) m_free(dtom(tp->t_template)); 298 299 free(tp, M_PCB); 300 #endif 301 u32ptr_done(pData, ptr_to_u32(pData, tp), tp); 294 302 #else /* VBOX_WITH_BSD_REASS */ 295 struct tseg_qent *te; 296 DEBUG_CALL("tcp_close"); 297 DEBUG_ARG("tp = %lx", (long )tp); 298 /*XXX: freeing the reassembly queue */ 299 LIST_FOREACH(te, &tp->t_segq, tqe_q) { 300 LIST_REMOVE(te, tqe_q); 301 m_freem(pData, te->tqe_m); 302 free(te); 303 tcp_reass_qsize--; 304 } 303 struct tseg_qent *te; 304 DEBUG_CALL("tcp_close"); 305 DEBUG_ARG("tp = %lx", (long )tp); 306 /*XXX: freeing the reassembly queue */ 307 LIST_FOREACH(te, &tp->t_segq, tqe_q) 308 { 309 LIST_REMOVE(te, tqe_q); 310 m_freem(pData, te->tqe_m); 311 free(te); 312 tcp_reass_qsize--; 313 } 305 314 #endif /* VBOX_WITH_BSD_REASS */ 306 307 308 309 310 311 312 313 314 315 316 317 315 free(tp); 316 so->so_tcpcb = 0; 317 soisfdisconnected(so); 318 /* clobber input socket cache if we're closing the cached connection */ 319 if (so == tcp_last_so) 320 tcp_last_so = &tcb; 321 closesocket(so->s); 322 sbfree(&so->so_rcv); 323 sbfree(&so->so_snd); 324 sofree(pData, so); 325 tcpstat.tcps_closed++; 326 return ((struct tcpcb *)0); 318 327 } 319 328 … … 321 330 tcp_drain() 322 331 { 323 332 /* XXX */ 324 333 } 325 334 … … 329 338 */ 330 339 331 #if def notdef340 #if 0 332 341 333 342 void 334 tcp_quench(i, errno) 335 336 int errno; 337 { 338 struct tcpcb *tp = intotcpcb(inp); 339 340 if (tp) 341 tp->snd_cwnd = tp->t_maxseg; 342 } 343 344 #endif /* notdef */ 343 tcp_quench(i, int errno) 344 { 345 struct tcpcb *tp = intotcpcb(inp); 346 347 if (tp) 348 tp->snd_cwnd = tp->t_maxseg; 349 } 350 351 #endif 345 352 346 353 /* … … 361 368 tcp_sockclosed(PNATState pData, struct tcpcb *tp) 362 369 { 363 364 DEBUG_CALL("tcp_sockclosed"); 365 DEBUG_ARG("tp = %lx", (long)tp); 366 367 switch (tp->t_state) { 368 370 DEBUG_CALL("tcp_sockclosed"); 371 DEBUG_ARG("tp = %lx", (long)tp); 372 373 switch (tp->t_state) 374 { 369 375 case TCPS_CLOSED: 370 376 case TCPS_LISTEN: 371 377 case TCPS_SYN_SENT: 372 373 374 378 tp->t_state = TCPS_CLOSED; 379 tp = tcp_close(pData, tp); 380 break; 375 381 376 382 case TCPS_SYN_RECEIVED: 377 383 case TCPS_ESTABLISHED: 378 379 384 tp->t_state = TCPS_FIN_WAIT_1; 385 break; 380 386 381 387 case TCPS_CLOSE_WAIT: 382 tp->t_state = TCPS_LAST_ACK; 383 break; 384 } 385 /* soisfdisconnecting(tp->t_socket); */ 386 if (tp && tp->t_state >= TCPS_FIN_WAIT_2) 387 soisfdisconnected(tp->t_socket); 388 if (tp) 389 tcp_output(pData, tp); 388 tp->t_state = TCPS_LAST_ACK; 389 break; 390 } 391 /* soisfdisconnecting(tp->t_socket); */ 392 if ( tp 393 && tp->t_state >= TCPS_FIN_WAIT_2) 394 soisfdisconnected(tp->t_socket); 395 if (tp) 396 tcp_output(pData, tp); 390 397 } 391 398 … … 402 409 int tcp_fconnect(PNATState pData, struct socket *so) 403 410 { 404 int ret=0; 405 406 DEBUG_CALL("tcp_fconnect"); 407 DEBUG_ARG("so = %lx", (long )so); 408 409 if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { 410 int opt, s=so->s; 411 struct sockaddr_in addr; 412 413 fd_nonblock(s); 414 opt = 1; 415 setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); 416 opt = 1; 417 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); 418 419 addr.sin_family = AF_INET; 420 if ((so->so_faddr.s_addr & htonl(pData->netmask)) == special_addr.s_addr) { 421 /* It's an alias */ 422 switch(ntohl(so->so_faddr.s_addr) & ~pData->netmask) { 423 case CTL_DNS: 424 if (!get_dns_addr(pData, &dns_addr)) 425 addr.sin_addr = dns_addr; 411 int ret=0; 412 413 DEBUG_CALL("tcp_fconnect"); 414 DEBUG_ARG("so = %lx", (long )so); 415 416 if ((ret = so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) 417 { 418 int opt, s=so->s; 419 struct sockaddr_in addr; 420 421 fd_nonblock(s); 422 opt = 1; 423 setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt, sizeof(opt)); 424 opt = 1; 425 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt, sizeof(opt)); 426 427 addr.sin_family = AF_INET; 428 if ((so->so_faddr.s_addr & htonl(pData->netmask)) == special_addr.s_addr) 429 { 430 /* It's an alias */ 431 switch(ntohl(so->so_faddr.s_addr) & ~pData->netmask) 432 { 433 case CTL_DNS: 434 if (!get_dns_addr(pData, &dns_addr)) 435 addr.sin_addr = dns_addr; 436 else 437 addr.sin_addr = loopback_addr; 438 break; 439 case CTL_ALIAS: 440 default: 441 addr.sin_addr = loopback_addr; 442 break; 443 } 444 } 426 445 else 427 addr.sin_addr = loopback_addr; 428 break; 429 case CTL_ALIAS: 430 default: 431 addr.sin_addr = loopback_addr; 432 break; 433 } 434 } else 435 addr.sin_addr = so->so_faddr; 436 addr.sin_port = so->so_fport; 437 438 DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " 439 "addr.sin_addr.s_addr=%.16s\n", 440 ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); 441 /* We don't care what port we get */ 442 ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); 443 444 /* 445 * If it's not in progress, it failed, so we just return 0, 446 * without clearing SS_NOFDREF 447 */ 448 soisfconnecting(so); 449 } 450 451 return(ret); 446 addr.sin_addr = so->so_faddr; 447 addr.sin_port = so->so_fport; 448 449 DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " 450 "addr.sin_addr.s_addr=%.16s\n", 451 ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); 452 /* We don't care what port we get */ 453 ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); 454 455 /* 456 * If it's not in progress, it failed, so we just return 0, 457 * without clearing SS_NOFDREF 458 */ 459 soisfconnecting(so); 460 } 461 462 return(ret); 452 463 } 453 464 … … 467 478 tcp_connect(PNATState pData, struct socket *inso) 468 479 { 469 struct socket *so; 470 struct sockaddr_in addr; 471 socklen_t addrlen = sizeof(struct sockaddr_in); 472 struct tcpcb *tp; 473 int s, opt; 474 475 DEBUG_CALL("tcp_connect"); 476 DEBUG_ARG("inso = %lx", (long)inso); 477 478 /* 479 * If it's an SS_ACCEPTONCE socket, no need to socreate() 480 * another socket, just use the accept() socket. 481 */ 482 if (inso->so_state & SS_FACCEPTONCE) { 483 /* FACCEPTONCE already have a tcpcb */ 484 so = inso; 485 } else { 486 if ((so = socreate()) == NULL) { 487 /* If it failed, get rid of the pending connection */ 488 closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); 489 return; 490 } 491 if (tcp_attach(pData, so) < 0) { 492 free(so); /* NOT sofree */ 493 return; 494 } 495 so->so_laddr = inso->so_laddr; 496 so->so_lport = inso->so_lport; 480 struct socket *so; 481 struct sockaddr_in addr; 482 socklen_t addrlen = sizeof(struct sockaddr_in); 483 struct tcpcb *tp; 484 int s, opt; 485 486 DEBUG_CALL("tcp_connect"); 487 DEBUG_ARG("inso = %lx", (long)inso); 488 489 /* 490 * If it's an SS_ACCEPTONCE socket, no need to socreate() 491 * another socket, just use the accept() socket. 492 */ 493 if (inso->so_state & SS_FACCEPTONCE) 494 { 495 /* FACCEPTONCE already have a tcpcb */ 496 so = inso; 497 } 498 else 499 { 500 if ((so = socreate()) == NULL) 501 { 502 /* If it failed, get rid of the pending connection */ 503 closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); 504 return; 497 505 } 498 499 (void) tcp_mss(pData, sototcpcb(so), 0); 500 501 if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { 502 tcp_close(pData, sototcpcb(so)); /* This will sofree() as well */ 503 return; 506 if (tcp_attach(pData, so) < 0) 507 { 508 free(so); /* NOT sofree */ 509 return; 504 510 } 505 fd_nonblock(s); 506 opt = 1; 507 setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 508 opt = 1; 509 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); 510 opt = 1; 511 setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); 512 513 so->so_fport = addr.sin_port; 514 so->so_faddr = addr.sin_addr; 515 /* Translate connections from localhost to the real hostname */ 516 if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) 517 so->so_faddr = alias_addr; 518 519 /* Close the accept() socket, set right state */ 520 if (inso->so_state & SS_FACCEPTONCE) { 521 closesocket(so->s); /* If we only accept once, close the accept() socket */ 522 so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ 523 /* if it's not FACCEPTONCE, it's already NOFDREF */ 524 } 525 so->s = s; 526 527 so->so_iptos = tcp_tos(so); 528 tp = sototcpcb(so); 529 530 tcp_template(tp); 531 532 /* Compute window scaling to request. */ 533 /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && 534 * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 535 * tp->request_r_scale++; 536 */ 537 538 /* soisconnecting(so); */ /* NOFDREF used instead */ 539 tcpstat.tcps_connattempt++; 540 541 tp->t_state = TCPS_SYN_SENT; 542 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 543 tp->iss = tcp_iss; 544 tcp_iss += TCP_ISSINCR/2; 545 tcp_sendseqinit(tp); 546 tcp_output(pData, tp); 511 so->so_laddr = inso->so_laddr; 512 so->so_lport = inso->so_lport; 513 } 514 515 (void) tcp_mss(pData, sototcpcb(so), 0); 516 517 if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) 518 { 519 tcp_close(pData, sototcpcb(so)); /* This will sofree() as well */ 520 return; 521 } 522 fd_nonblock(s); 523 opt = 1; 524 setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 525 opt = 1; 526 setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); 527 opt = 1; 528 setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); 529 530 so->so_fport = addr.sin_port; 531 so->so_faddr = addr.sin_addr; 532 /* Translate connections from localhost to the real hostname */ 533 if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) 534 so->so_faddr = alias_addr; 535 536 /* Close the accept() socket, set right state */ 537 if (inso->so_state & SS_FACCEPTONCE) 538 { 539 closesocket(so->s); /* If we only accept once, close the accept() socket */ 540 so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ 541 /* if it's not FACCEPTONCE, it's already NOFDREF */ 542 } 543 so->s = s; 544 545 so->so_iptos = tcp_tos(so); 546 tp = sototcpcb(so); 547 548 tcp_template(tp); 549 550 /* Compute window scaling to request. */ 551 /* while (tp->request_r_scale < TCP_MAX_WINSHIFT 552 * && (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) 553 * tp->request_r_scale++; 554 */ 555 556 /* soisconnecting(so); */ /* NOFDREF used instead */ 557 tcpstat.tcps_connattempt++; 558 559 tp->t_state = TCPS_SYN_SENT; 560 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; 561 tp->iss = tcp_iss; 562 tcp_iss += TCP_ISSINCR/2; 563 tcp_sendseqinit(tp); 564 tcp_output(pData, tp); 547 565 } 548 566 … … 553 571 tcp_attach(PNATState pData, struct socket *so) 554 572 { 555 if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL) 556 return -1; 557 558 insque(pData, so, &tcb); 559 560 return 0; 573 if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL) 574 return -1; 575 576 insque(pData, so, &tcb); 577 return 0; 561 578 } 562 579 … … 564 581 * Set the socket's type of service field 565 582 */ 566 static const struct tos_t tcptos[] = { 567 {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ 568 {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ 569 {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ 570 {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ 571 {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ 572 {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ 573 {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ 574 {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ 575 {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ 576 {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ 577 {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ 578 {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ 579 {0, 0, 0, 0} 583 static const struct tos_t tcptos[] = 584 { 585 {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ 586 {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ 587 {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ 588 {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ 589 {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ 590 {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ 591 {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ 592 {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ 593 {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ 594 {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ 595 {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ 596 {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ 597 {0, 0, 0, 0} 580 598 }; 581 599 … … 584 602 */ 585 603 u_int8_t 586 tcp_tos(so) 587 struct socket *so; 588 { 589 int i = 0; 590 591 while(tcptos[i].tos) { 592 if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || 593 (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { 594 so->so_emu = tcptos[i].emu; 595 return tcptos[i].tos; 596 } 597 i++; 604 tcp_tos(struct socket *so) 605 { 606 int i = 0; 607 608 while(tcptos[i].tos) 609 { 610 if ( (tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) 611 || (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) 612 { 613 so->so_emu = tcptos[i].emu; 614 return tcptos[i].tos; 598 615 } 599 600 return 0; 601 } 602 603 /* 604 * Emulate programs that try and connect to us 605 * This includes ftp (the data connection is 606 * initiated by the server) and IRC (DCC CHAT and 607 * DCC SEND) for now 616 i++; 617 } 618 619 return 0; 620 } 621 622 /* 623 * Emulate programs that try and connect to us. This includes ftp (the data 624 * connection is initiated by the server) and IRC (DCC CHAT and DCC SEND) 625 * for now 608 626 * 609 * NOTE: It's possible to crash SLiRP by sending it 610 * unstandard strings to emulate... if this is a problem, 611 * more checks are needed here 627 * NOTE: It's possible to crash SLiRP by sending it unstandard strings to 628 * emulate... if this is a problem, more checks are needed here. 612 629 * 613 * XXX Assumes the whole command came in one packet630 * XXX Assumes the whole command cames in one packet 614 631 * 615 * XXX Some ftp clients will have their TOS set to 616 * LOWDELAY and so Nagel will kick in. Because of this, 617 * we'll get the first letter, followed by the rest, so 618 * we simply scan for ORT instead of PORT... 619 * DCC doesn't have this problem because there's other stuff 620 * in the packet before the DCC command. 632 * XXX Some ftp clients will have their TOS set to LOWDELAY and so Nagel will 633 * kick in. Because of this, we'll get the first letter, followed by the 634 * rest, so we simply scan for ORT instead of PORT... DCC doesn't have this 635 * problem because there's other stuff in the packet before the DCC command. 621 636 * 622 * Return 1 if the mbuf m is still valid and should be 623 * sbappend()ed 637 * Return 1 if the mbuf m is still valid and should be sbappend()ed 624 638 * 625 639 * NOTE: if you return 0 you MUST m_free() the mbuf! … … 628 642 tcp_emu(PNATState pData, struct socket *so, struct mbuf *m) 629 643 { 630 u_int n1, n2, n3, n4, n5, n6; 631 char buff[256]; 632 u_int32_t laddr; 633 u_int lport; 634 char *bptr; 635 636 DEBUG_CALL("tcp_emu"); 637 DEBUG_ARG("so = %lx", (long)so); 638 DEBUG_ARG("m = %lx", (long)m); 639 640 switch(so->so_emu) { 641 int x, i; 642 643 case EMU_IDENT: 644 u_int n1, n2, n3, n4, n5, n6; 645 char buff[256]; 646 u_int32_t laddr; 647 u_int lport; 648 char *bptr; 649 650 DEBUG_CALL("tcp_emu"); 651 DEBUG_ARG("so = %lx", (long)so); 652 DEBUG_ARG("m = %lx", (long)m); 653 654 switch(so->so_emu) 655 { 656 int x, i; 657 658 case EMU_IDENT: 659 /* 660 * Identification protocol as per rfc-1413 661 */ 662 { 663 struct socket *tmpso; 664 struct sockaddr_in addr; 665 socklen_t addrlen = sizeof(struct sockaddr_in); 666 struct sbuf *so_rcv = &so->so_rcv; 667 668 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 669 so_rcv->sb_wptr += m->m_len; 670 so_rcv->sb_rptr += m->m_len; 671 m->m_data[m->m_len] = 0; /* NULL terminate */ 672 if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) 673 { 674 if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) 675 { 676 HTONS(n1); 677 HTONS(n2); 678 /* n2 is the one on our host */ 679 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) 680 { 681 if ( tmpso->so_laddr.s_addr == so->so_laddr.s_addr 682 && tmpso->so_lport == n2 683 && tmpso->so_faddr.s_addr == so->so_faddr.s_addr 684 && tmpso->so_fport == n1) 685 { 686 if (getsockname(tmpso->s, 687 (struct sockaddr *)&addr, &addrlen) == 0) 688 n2 = ntohs(addr.sin_port); 689 break; 690 } 691 } 692 } 693 so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); 694 so_rcv->sb_rptr = so_rcv->sb_data; 695 so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; 696 } 697 m_free(pData, m); 698 return 0; 699 } 700 701 case EMU_FTP: 702 *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ 703 if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) 704 { 644 705 /* 645 * Identification protocol as per rfc-1413706 * Need to emulate the PORT command 646 707 */ 647 708 x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", 709 &n1, &n2, &n3, &n4, &n5, &n6, buff); 710 if (x < 6) 711 return 1; 712 713 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 714 lport = htons((n5 << 8) | (n6)); 715 716 if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL) 717 return 1; 718 719 n6 = ntohs(so->so_fport); 720 721 n5 = (n6 >> 8) & 0xff; 722 n6 &= 0xff; 723 724 laddr = ntohl(so->so_faddr.s_addr); 725 726 n1 = ((laddr >> 24) & 0xff); 727 n2 = ((laddr >> 16) & 0xff); 728 n3 = ((laddr >> 8) & 0xff); 729 n4 = ( laddr & 0xff); 730 731 m->m_len = bptr - m->m_data; /* Adjust length */ 732 m->m_len += sprintf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%s", 733 n1, n2, n3, n4, n5, n6, x==7?buff:""); 734 return 1; 735 } 736 else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) 737 { 738 /* 739 * Need to emulate the PASV response 740 */ 741 x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", 742 &n1, &n2, &n3, &n4, &n5, &n6, buff); 743 if (x < 6) 744 return 1; 745 746 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 747 lport = htons((n5 << 8) | (n6)); 748 749 if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL) 750 return 1; 751 752 n6 = ntohs(so->so_fport); 753 754 n5 = (n6 >> 8) & 0xff; 755 n6 &= 0xff; 756 757 laddr = ntohl(so->so_faddr.s_addr); 758 759 n1 = ((laddr >> 24) & 0xff); 760 n2 = ((laddr >> 16) & 0xff); 761 n3 = ((laddr >> 8) & 0xff); 762 n4 = (laddr & 0xff); 763 764 m->m_len = bptr - m->m_data; /* Adjust length */ 765 m->m_len += sprintf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", 766 n1, n2, n3, n4, n5, n6, x==7?buff:""); 767 768 return 1; 769 } 770 return 1; 771 772 case EMU_KSH: 773 /* 774 * The kshell (Kerberos rsh) and shell services both pass 775 * a local port port number to carry signals to the server 776 * and stderr to the client. It is passed at the beginning 777 * of the connection as a NUL-terminated decimal ASCII string. 778 */ 779 so->so_emu = 0; 780 for (lport = 0, i = 0; i < m->m_len-1; ++i) 781 { 782 if (m->m_data[i] < '0' || m->m_data[i] > '9') 783 return 1; /* invalid number */ 784 lport *= 10; 785 lport += m->m_data[i] - '0'; 786 } 787 if ( m->m_data[m->m_len-1] == '\0' 788 && lport != 0 789 && (so = solisten(pData, 0, so->so_laddr.s_addr, 790 htons(lport), SS_FACCEPTONCE)) != NULL) 791 m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; 792 return 1; 793 794 case EMU_IRC: 795 /* 796 * Need to emulate DCC CHAT, DCC SEND and DCC MOVE 797 */ 798 *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ 799 if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) 800 return 1; 801 802 /* The %256s is for the broken mIRC */ 803 if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) 804 { 805 if ((so = solisten(pData, 0, htonl(laddr), 806 htons(lport), SS_FACCEPTONCE)) == NULL) 807 return 1; 808 809 m->m_len = bptr - m->m_data; /* Adjust length */ 810 m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", 811 (unsigned long)ntohl(so->so_faddr.s_addr), 812 ntohs(so->so_fport), 1); 813 } 814 else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) 815 { 816 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 817 return 1; 818 819 m->m_len = bptr - m->m_data; /* Adjust length */ 820 m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", 821 buff, (unsigned long)ntohl(so->so_faddr.s_addr), 822 ntohs(so->so_fport), n1, 1); 823 } 824 else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) 825 { 826 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 827 return 1; 828 829 m->m_len = bptr - m->m_data; /* Adjust length */ 830 m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", 831 buff, (unsigned long)ntohl(so->so_faddr.s_addr), 832 ntohs(so->so_fport), n1, 1); 833 } 834 return 1; 835 836 #ifdef VBOX 837 /** @todo Disabled EMU_REALAUDIO, because it uses a static variable. 838 * This is not legal when more than one slirp instance is active. */ 839 #else /* !VBOX */ 840 case EMU_REALAUDIO: 841 /* 842 * RealAudio emulation - JP. We must try to parse the incoming 843 * data and try to find the two characters that contain the 844 * port number. Then we redirect an udp port and replace the 845 * number with the real port we got. 846 * 847 * The 1.0 beta versions of the player are not supported 848 * any more. 849 * 850 * A typical packet for player version 1.0 (release version): 851 * 852 * 0000:50 4E 41 00 05 853 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P 854 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH 855 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v 856 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB 857 * 858 * Now the port number 0x1BD7 is found at offset 0x04 of the 859 * Now the port number 0x1BD7 is found at offset 0x04 of the 860 * second packet. This time we received five bytes first and 861 * then the rest. You never know how many bytes you get. 862 * 863 * A typical packet for player version 2.0 (beta): 864 * 865 * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. 866 * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 867 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ 868 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas 869 * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B 870 * 871 * Port number 0x1BC1 is found at offset 0x0d. 872 * 873 * This is just a horrible switch statement. Variable ra tells 874 * us where we're going. 875 */ 876 877 bptr = m->m_data; 878 while (bptr < m->m_data + m->m_len) 879 { 880 u_short p; 881 static int ra = 0; 882 char ra_tbl[4]; 883 884 ra_tbl[0] = 0x50; 885 ra_tbl[1] = 0x4e; 886 ra_tbl[2] = 0x41; 887 ra_tbl[3] = 0; 888 889 switch (ra) 648 890 { 649 struct socket *tmpso; 650 struct sockaddr_in addr; 651 socklen_t addrlen = sizeof(struct sockaddr_in); 652 struct sbuf *so_rcv = &so->so_rcv; 653 654 memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); 655 so_rcv->sb_wptr += m->m_len; 656 so_rcv->sb_rptr += m->m_len; 657 m->m_data[m->m_len] = 0; /* NULL terminate */ 658 if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { 659 if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { 660 HTONS(n1); 661 HTONS(n2); 662 /* n2 is the one on our host */ 663 for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { 664 if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && 665 tmpso->so_lport == n2 && 666 tmpso->so_faddr.s_addr == so->so_faddr.s_addr && 667 tmpso->so_fport == n1) { 668 if (getsockname(tmpso->s, 669 (struct sockaddr *)&addr, &addrlen) == 0) 670 n2 = ntohs(addr.sin_port); 671 break; 672 } 673 } 674 } 675 so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); 676 so_rcv->sb_rptr = so_rcv->sb_data; 677 so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; 891 case 0: 892 case 2: 893 case 3: 894 if (*bptr++ != ra_tbl[ra]) 895 { 896 ra = 0; 897 continue; 678 898 } 679 m_free(pData, m); 680 return 0; 899 break; 900 901 case 1: 902 /* 903 * We may get 0x50 several times, ignore them 904 */ 905 if (*bptr == 0x50) 906 { 907 ra = 1; 908 bptr++; 909 continue; 910 } 911 else if (*bptr++ != ra_tbl[ra]) 912 { 913 ra = 0; 914 continue; 915 } 916 break; 917 918 case 4: 919 /* 920 * skip version number 921 */ 922 bptr++; 923 break; 924 925 case 5: 926 /* 927 * The difference between versions 1.0 and 928 * 2.0 is here. For future versions of 929 * the player this may need to be modified. 930 */ 931 if (*(bptr + 1) == 0x02) 932 bptr += 8; 933 else 934 bptr += 4; 935 break; 936 937 case 6: 938 /* This is the field containing the port 939 * number that RA-player is listening to. 940 */ 941 lport = (((u_char*)bptr)[0] << 8) 942 + ((u_char *)bptr)[1]; 943 if (lport < 6970) 944 lport += 256; /* don't know why */ 945 if (lport < 6970 || lport > 7170) 946 return 1; /* failed */ 947 948 /* try to get udp port between 6970 - 7170 */ 949 for (p = 6970; p < 7071; p++) 950 { 951 if (udp_listen(htons(p), 952 so->so_laddr.s_addr, 953 htons(lport), 954 SS_FACCEPTONCE)) 955 { 956 break; 957 } 958 } 959 if (p == 7071) 960 p = 0; 961 *(u_char *)bptr++ = (p >> 8) & 0xff; 962 *(u_char *)bptr++ = p & 0xff; 963 ra = 0; 964 return 1; /* port redirected, we're done */ 965 break; 966 967 default: 968 ra = 0; 681 969 } 682 683 case EMU_FTP: /* ftp */ 684 *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ 685 if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { 686 /* 687 * Need to emulate the PORT command 688 */ 689 x = sscanf(bptr, "ORT %u,%u,%u,%u,%u,%u\r\n%256[^\177]", 690 &n1, &n2, &n3, &n4, &n5, &n6, buff); 691 if (x < 6) 692 return 1; 693 694 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 695 lport = htons((n5 << 8) | (n6)); 696 697 if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL) 698 return 1; 699 700 n6 = ntohs(so->so_fport); 701 702 n5 = (n6 >> 8) & 0xff; 703 n6 &= 0xff; 704 705 laddr = ntohl(so->so_faddr.s_addr); 706 707 n1 = ((laddr >> 24) & 0xff); 708 n2 = ((laddr >> 16) & 0xff); 709 n3 = ((laddr >> 8) & 0xff); 710 n4 = (laddr & 0xff); 711 712 m->m_len = bptr - m->m_data; /* Adjust length */ 713 m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", 714 n1, n2, n3, n4, n5, n6, x==7?buff:""); 715 return 1; 716 } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { 717 /* 718 * Need to emulate the PASV response 719 */ 720 x = sscanf(bptr, "27 Entering Passive Mode (%u,%u,%u,%u,%u,%u)\r\n%256[^\177]", 721 &n1, &n2, &n3, &n4, &n5, &n6, buff); 722 if (x < 6) 723 return 1; 724 725 laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); 726 lport = htons((n5 << 8) | (n6)); 727 728 if ((so = solisten(pData, 0, laddr, lport, SS_FACCEPTONCE)) == NULL) 729 return 1; 730 731 n6 = ntohs(so->so_fport); 732 733 n5 = (n6 >> 8) & 0xff; 734 n6 &= 0xff; 735 736 laddr = ntohl(so->so_faddr.s_addr); 737 738 n1 = ((laddr >> 24) & 0xff); 739 n2 = ((laddr >> 16) & 0xff); 740 n3 = ((laddr >> 8) & 0xff); 741 n4 = (laddr & 0xff); 742 743 m->m_len = bptr - m->m_data; /* Adjust length */ 744 m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", 745 n1, n2, n3, n4, n5, n6, x==7?buff:""); 746 747 return 1; 748 } 749 750 return 1; 751 752 case EMU_KSH: 753 /* 754 * The kshell (Kerberos rsh) and shell services both pass 755 * a local port port number to carry signals to the server 756 * and stderr to the client. It is passed at the beginning 757 * of the connection as a NUL-terminated decimal ASCII string. 758 */ 759 so->so_emu = 0; 760 for (lport = 0, i = 0; i < m->m_len-1; ++i) { 761 if (m->m_data[i] < '0' || m->m_data[i] > '9') 762 return 1; /* invalid number */ 763 lport *= 10; 764 lport += m->m_data[i] - '0'; 765 } 766 if (m->m_data[m->m_len-1] == '\0' && lport != 0 && 767 (so = solisten(pData, 0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) 768 m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; 769 return 1; 770 771 case EMU_IRC: 772 /* 773 * Need to emulate DCC CHAT, DCC SEND and DCC MOVE 774 */ 775 *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ 776 if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) 777 return 1; 778 779 /* The %256s is for the broken mIRC */ 780 if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { 781 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 782 return 1; 783 784 m->m_len = bptr - m->m_data; /* Adjust length */ 785 m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", 786 (unsigned long)ntohl(so->so_faddr.s_addr), 787 ntohs(so->so_fport), 1); 788 } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 789 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 790 return 1; 791 792 m->m_len = bptr - m->m_data; /* Adjust length */ 793 m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", 794 buff, (unsigned long)ntohl(so->so_faddr.s_addr), 795 ntohs(so->so_fport), n1, 1); 796 } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { 797 if ((so = solisten(pData, 0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) 798 return 1; 799 800 m->m_len = bptr - m->m_data; /* Adjust length */ 801 m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", 802 buff, (unsigned long)ntohl(so->so_faddr.s_addr), 803 ntohs(so->so_fport), n1, 1); 804 } 805 return 1; 806 807 #ifdef VBOX 808 /** @todo Disabled EMU_REALAUDIO, because it uses a static variable. 809 * This is not legal when more than one slirp instance is active. */ 810 #else /* !VBOX */ 811 case EMU_REALAUDIO: 812 /* 813 * RealAudio emulation - JP. We must try to parse the incoming 814 * data and try to find the two characters that contain the 815 * port number. Then we redirect an udp port and replace the 816 * number with the real port we got. 817 * 818 * The 1.0 beta versions of the player are not supported 819 * any more. 820 * 821 * A typical packet for player version 1.0 (release version): 822 * 823 * 0000:50 4E 41 00 05 824 * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P 825 * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH 826 * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v 827 * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB 828 * 829 * Now the port number 0x1BD7 is found at offset 0x04 of the 830 * Now the port number 0x1BD7 is found at offset 0x04 of the 831 * second packet. This time we received five bytes first and 832 * then the rest. You never know how many bytes you get. 833 * 834 * A typical packet for player version 2.0 (beta): 835 * 836 * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. 837 * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 838 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ 839 * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas 840 * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B 841 * 842 * Port number 0x1BC1 is found at offset 0x0d. 843 * 844 * This is just a horrible switch statement. Variable ra tells 845 * us where we're going. 846 */ 847 848 bptr = m->m_data; 849 while (bptr < m->m_data + m->m_len) { 850 u_short p; 851 static int ra = 0; 852 char ra_tbl[4]; 853 854 ra_tbl[0] = 0x50; 855 ra_tbl[1] = 0x4e; 856 ra_tbl[2] = 0x41; 857 ra_tbl[3] = 0; 858 859 switch (ra) { 860 case 0: 861 case 2: 862 case 3: 863 if (*bptr++ != ra_tbl[ra]) { 864 ra = 0; 865 continue; 866 } 867 break; 868 869 case 1: 870 /* 871 * We may get 0x50 several times, ignore them 872 */ 873 if (*bptr == 0x50) { 874 ra = 1; 875 bptr++; 876 continue; 877 } else if (*bptr++ != ra_tbl[ra]) { 878 ra = 0; 879 continue; 880 } 881 break; 882 883 case 4: 884 /* 885 * skip version number 886 */ 887 bptr++; 888 break; 889 890 case 5: 891 /* 892 * The difference between versions 1.0 and 893 * 2.0 is here. For future versions of 894 * the player this may need to be modified. 895 */ 896 if (*(bptr + 1) == 0x02) 897 bptr += 8; 898 else 899 bptr += 4; 900 break; 901 902 case 6: 903 /* This is the field containing the port 904 * number that RA-player is listening to. 905 */ 906 lport = (((u_char*)bptr)[0] << 8) 907 + ((u_char *)bptr)[1]; 908 if (lport < 6970) 909 lport += 256; /* don't know why */ 910 if (lport < 6970 || lport > 7170) 911 return 1; /* failed */ 912 913 /* try to get udp port between 6970 - 7170 */ 914 for (p = 6970; p < 7071; p++) { 915 if (udp_listen( htons(p), 916 so->so_laddr.s_addr, 917 htons(lport), 918 SS_FACCEPTONCE)) { 919 break; 920 } 921 } 922 if (p == 7071) 923 p = 0; 924 *(u_char *)bptr++ = (p >> 8) & 0xff; 925 *(u_char *)bptr++ = p & 0xff; 926 ra = 0; 927 return 1; /* port redirected, we're done */ 928 break; 929 930 default: 931 ra = 0; 932 } 933 ra++; 934 } 935 return 1; 970 ra++; 971 } 972 return 1; 936 973 #endif /* !VBOX */ 937 974 938 939 940 941 942 975 default: 976 /* Ooops, not emulated, won't call tcp_emu again */ 977 so->so_emu = 0; 978 return 1; 979 } 943 980 } 944 981
Note:
See TracChangeset
for help on using the changeset viewer.