📄 tcp.c
字号:
342 }
343 #endif
344 if (before(counted, skb->h.th->seq)) /* Found a hole so stops here */
345 break;
346 sum = skb->len -(counted - skb->h.th->seq); /* Length - header but start from where we are up to (avoid overlaps) */
347 if (skb->h.th->syn)
348 sum++;
349 if (sum >= 0) { /* Add it up, move on */
350 amount += sum;
351 if (skb->h.th->syn) amount--;
352 counted += sum;
353 }
354 if (amount && skb->h.th->psh) break;
355 skb =(struct sk_buff *)skb->next; /* Move along */
356 } while(skb != sk->rqueue);
357 if (amount && !sk->urginline && sk->urg_data &&
358 (sk->urg_seq - sk->copied_seq) <= (counted - sk->copied_seq))
359 amount--; /* don't count urg data */
360 restore_flags(flags);
361 DPRINTF((DBG_TCP, "tcp readable returning %d bytes\n", amount));
362 if(sk->debug)
363 printk("got %lu bytes.\n",amount);
364 return(amount);
365 }
366
367
368 /*
369 * Wait for a TCP event. Note the oddity with SEL_IN and reading. The
370 * listening socket has a receive queue of sockets to accept.
371 */
372
373 static int
374 tcp_select(struct sock *sk, int sel_type, select_table *wait)
375 {
376 DPRINTF((DBG_TCP, "tcp_select(sk=%X, sel_type = %d, wait = %X)\n",
377 sk, sel_type, wait));
378
379 sk->inuse = 1;
380 switch(sel_type) {
381 case SEL_IN:
382 if(sk->debug)
383 printk("select in");
384 select_wait(sk->sleep, wait);
385 if(sk->debug)
386 printk("-select out");
387 if (skb_peek(&sk->rqueue) != NULL) {
388 if (sk->state == TCP_LISTEN || tcp_readable(sk)) {
389 release_sock(sk);
390 if(sk->debug)
391 printk("-select ok data\n");
392 return(1);
393 }
394 }
395 if (sk->err != 0) /* Receiver error */
396 {
397 release_sock(sk);
398 if(sk->debug)
399 printk("-select ok error");
400 return(1);
401 }
402 if (sk->shutdown & RCV_SHUTDOWN) {
403 release_sock(sk);
404 if(sk->debug)
405 printk("-select ok down\n");
406 return(1);
407 } else {
408 release_sock(sk);
409 if(sk->debug)
410 printk("-select fail\n");
411 return(0);
412 }
413 case SEL_OUT:
414 select_wait(sk->sleep, wait);
415 if (sk->shutdown & SEND_SHUTDOWN) {
416 DPRINTF((DBG_TCP,
417 "write select on shutdown socket.\n"));
418
419 /* FIXME: should this return an error? */
420 release_sock(sk);
421 return(0);
422 }
423
424 /*
425 * FIXME:
426 * Hack so it will probably be able to write
427 * something if it says it's ok to write.
428 */
429 if (sk->prot->wspace(sk) >= sk->mss) {
430 release_sock(sk);
431 /* This should cause connect to work ok. */
432 if (sk->state == TCP_SYN_RECV ||
433 sk->state == TCP_SYN_SENT) return(0);
434 return(1);
435 }
436 DPRINTF((DBG_TCP,
437 "tcp_select: sleeping on write sk->wmem_alloc = %d, "
438 "sk->packets_out = %d\n"
439 "sk->wback = %X, sk->wfront = %X\n"
440 "sk->write_seq = %u, sk->window_seq=%u\n",
441 sk->wmem_alloc, sk->packets_out,
442 sk->wback, sk->wfront,
443 sk->write_seq, sk->window_seq));
444
445 release_sock(sk);
446 return(0);
447 case SEL_EX:
448 select_wait(sk->sleep,wait);
449 if (sk->err || sk->urg_data) {
450 release_sock(sk);
451 return(1);
452 }
453 release_sock(sk);
454 return(0);
455 }
456
457 release_sock(sk);
458 return(0);
459 }
460
461
462 int
463 tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
464 {
465 int err;
466 DPRINTF((DBG_TCP, "tcp_ioctl(sk=%X, cmd = %d, arg=%X)\n", sk, cmd, arg));
467 switch(cmd) {
468 case DDIOCSDBG:
469 return(dbg_ioctl((void *) arg, DBG_TCP));
470
471 case TIOCINQ:
472 #ifdef FIXME /* FIXME: */
473 case FIONREAD:
474 #endif
475 {
476 unsigned long amount;
477
478 if (sk->state == TCP_LISTEN) return(-EINVAL);
479
480 sk->inuse = 1;
481 amount = tcp_readable(sk);
482 release_sock(sk);
483 DPRINTF((DBG_TCP, "returning %d\n", amount));
484 err=verify_area(VERIFY_WRITE,(void *)arg,
485 sizeof(unsigned long));
486 if(err)
487 return err;
488 put_fs_long(amount,(unsigned long *)arg);
489 return(0);
490 }
491 case SIOCATMARK:
492 {
493 int answ = sk->urg_data && sk->urg_seq == sk->copied_seq+1;
494
495 err = verify_area(VERIFY_WRITE,(void *) arg,
496 sizeof(unsigned long));
497 if (err)
498 return err;
499 put_fs_long(answ,(int *) arg);
500 return(0);
501 }
502 case TIOCOUTQ:
503 {
504 unsigned long amount;
505
506 if (sk->state == TCP_LISTEN) return(-EINVAL);
507 amount = sk->prot->wspace(sk);
508 err=verify_area(VERIFY_WRITE,(void *)arg,
509 sizeof(unsigned long));
510 if(err)
511 return err;
512 put_fs_long(amount,(unsigned long *)arg);
513 return(0);
514 }
515 default:
516 return(-EINVAL);
517 }
518 }
519
520
521 /* This routine computes a TCP checksum. */
522 unsigned short
523 tcp_check(struct tcphdr *th, int len,
524 unsigned long saddr, unsigned long daddr)
525 {
526 unsigned long sum;
527
528 if (saddr == 0) saddr = my_addr();
529 print_th(th);
530 __asm__("\t addl %%ecx,%%ebx\n"
531 "\t adcl %%edx,%%ebx\n"
532 "\t adcl $0, %%ebx\n"
533 : "=b"(sum)
534 : ""(daddr), "c"(saddr), "d"((ntohs(len) << 16) + IPPROTO_TCP*256)
535 : "cx","bx","dx" );
536
537 if (len > 3) {
538 __asm__("\tclc\n"
539 "1:\n"
540 "\t lodsl\n"
541 "\t adcl %%eax, %%ebx\n"
542 "\t loop 1b\n"
543 "\t adcl $0, %%ebx\n"
544 : "=b"(sum) , "=S"(th)
545 : ""(sum), "c"(len/4) ,"1"(th)
546 : "ax", "cx", "bx", "si" );
547 }
548
549 /* Convert from 32 bits to 16 bits. */
550 __asm__("\t movl %%ebx, %%ecx\n"
551 "\t shrl $16,%%ecx\n"
552 "\t addw %%cx, %%bx\n"
553 "\t adcw $0, %%bx\n"
554 : "=b"(sum)
555 : ""(sum)
556 : "bx", "cx");
557
558 /* Check for an extra word. */
559 if ((len & 2) != 0) {
560 __asm__("\t lodsw\n"
561 "\t addw %%ax,%%bx\n"
562 "\t adcw $0, %%bx\n"
563 : "=b"(sum), "=S"(th)
564 : ""(sum) ,"1"(th)
565 : "si", "ax", "bx");
566 }
567
568 /* Now check for the extra byte. */
569 if ((len & 1) != 0) {
570 __asm__("\t lodsb\n"
571 "\t movb $0,%%ah\n"
572 "\t addw %%ax,%%bx\n"
573 "\t adcw $0, %%bx\n"
574 : "=b"(sum)
575 : ""(sum) ,"S"(th)
576 : "si", "ax", "bx");
577 }
578
579 /* We only want the bottom 16 bits, but we never cleared the top 16. */
580 return((~sum) & 0xffff);
581 }
582
583
584 void tcp_send_check(struct tcphdr *th, unsigned long saddr,
585 unsigned long daddr, int len, struct sock *sk)
586 {
587 th->check = 0;
588 th->check = tcp_check(th, len, saddr, daddr);
589 return;
590 }
591
592 static void tcp_send_skb(struct sock *sk, struct sk_buff *skb)
593 {
594 int size;
595 struct tcphdr * th = skb->h.th;
596
597 /* length of packet (not counting length of pre-tcp headers) */
598 size = skb->len - ((unsigned char *) th - skb->data);
599
600 /* sanity check it.. */
601 if (size < sizeof(struct tcphdr) || size > skb->len) {
602 printk("tcp_send_skb: bad skb (skb = %p, data = %p, th = %p, len = %lu)\n",
603 skb, skb->data, th, skb->len);
604 kfree_skb(skb, FREE_WRITE);
605 return;
606 }
607
608 /* If we have queued a header size packet.. */
609 if (size == sizeof(struct tcphdr)) {
610 /* If its got a syn or fin its notionally included in the size..*/
611 if(!th->syn && !th->fin) {
612 printk("tcp_send_skb: attempt to queue a bogon.\n");
613 kfree_skb(skb,FREE_WRITE);
614 return;
615 }
616 }
617
618 /* We need to complete and send the packet. */
619 tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
620
621 skb->h.seq = ntohl(th->seq) + size - 4*th->doff;
622 if (after(skb->h.seq, sk->window_seq) ||
623 (sk->retransmits && sk->timeout == TIME_WRITE) ||
624 sk->packets_out >= sk->cong_window) {
625 DPRINTF((DBG_TCP, "sk->cong_window = %d, sk->packets_out = %d\n",
626 sk->cong_window, sk->packets_out));
627 DPRINTF((DBG_TCP, "sk->write_seq = %d, sk->window_seq = %d\n",
628 sk->write_seq, sk->window_seq));
629 skb->next = NULL;
630 skb->magic = TCP_WRITE_QUEUE_MAGIC;
631 if (sk->wback == NULL) {
632 sk->wfront = skb;
633 } else {
634 sk->wback->next = skb;
635 }
636 sk->wback = skb;
637 if (before(sk->window_seq, sk->wfront->h.seq) &&
638 sk->send_head == NULL &&
639 sk->ack_backlog == 0)
640 reset_timer(sk, TIME_PROBE0, sk->rto);
641 } else {
642 sk->sent_seq = sk->write_seq;
643 sk->prot->queue_xmit(sk, skb->dev, skb, 0);
644 }
645 }
646
647 struct sk_buff * tcp_dequeue_partial(struct sock * sk)
648 {
649 struct sk_buff * skb;
650 unsigned long flags;
651
652 save_flags(flags);
653 cli();
654 skb = sk->partial;
655 if (skb) {
656 sk->partial = NULL;
657 del_timer(&sk->partial_timer);
658 }
659 restore_flags(flags);
660 return skb;
661 }
662
663 static void tcp_send_partial(struct sock *sk)
664 {
665 struct sk_buff *skb;
666
667 if (sk == NULL)
668 return;
669 while ((skb = tcp_dequeue_partial(sk)) != NULL)
670 tcp_send_skb(sk, skb);
671 }
672
673 void tcp_enqueue_partial(struct sk_buff * skb, struct sock * sk)
674 {
675 struct sk_buff * tmp;
676 unsigned long flags;
677
678 save_flags(flags);
679 cli();
680 tmp = sk->partial;
681 if (tmp)
682 del_timer(&sk->partial_timer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -