⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sock.c

📁 An implementation of the TCP/IP protocol suite for the LINUX operating system. INET is implemented u
💻 C
📖 第 1 页 / 共 5 页
字号:
381                 cli();
382                 /* see if it's in a transmit queue. */
383                 /* this can be simplified quite a bit.  Look */
384                 /* at tcp.c:tcp_ack to see how. */
385                 if (skb->next != NULL) 
386                 {
387                         IS_SKB(skb);
388                         skb_unlink(skb);
389                 }
390                 skb->dev = NULL;
391                 sti();
392                 skb2 = (struct sk_buff *)skb->link3;
393                 kfree_skb(skb, FREE_WRITE);
394                 skb = skb2;
395         }       
396         sk->send_head = NULL;
397 
398         /* And now the backlog. */
399         if (sk->back_log != NULL) 
400         {
401                 /* this should never happen. */
402                 printk("cleaning back_log. \n");
403                 cli();
404                 skb = (struct sk_buff *)sk->back_log;
405                 do 
406                 {
407                         struct sk_buff *skb2;
408         
409                         skb2 = (struct sk_buff *)skb->next;
410                         kfree_skb(skb, FREE_READ);
411                         skb = skb2;
412                 }
413                 while(skb != sk->back_log);
414                 sti();
415         }
416         sk->back_log = NULL;
417 
418   /* Now if it has a half accepted/ closed socket. */
419         if (sk->pair) 
420         {
421                 sk->pair->dead = 1;
422                 sk->pair->prot->close(sk->pair, 0);
423                 sk->pair = NULL;
424         }
425 
426   /*
427    * Now if everything is gone we can free the socket
428    * structure, otherwise we need to keep it around until
429    * everything is gone.
430    */
431           if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
432           {
433                 kfree_s((void *)sk,sizeof(*sk));
434           } 
435           else 
436           {
437                 /* this should never happen. */
438                 /* actually it can if an ack has just been sent. */
439                 DPRINTF((DBG_INET, "possible memory leak in socket = %X\n", sk));
440                 sk->destroy = 1;
441                 sk->ack_backlog = 0;
442                 sk->inuse = 0;
443                 reset_timer(sk, TIME_DESTROY, SOCK_DESTROY_TIME);
444         }
445         DPRINTF((DBG_INET, "leaving destroy_sock\n"));
446 }
447 
448 
449 static int
450 inet_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
451 {
452   struct sock *sk;
453 
454   sk = (struct sock *) sock->data;
455   if (sk == NULL) {
456         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
457         return(0);
458   }
459 
460   switch(cmd) {
461         case F_SETOWN:
462                 /*
463                  * This is a little restrictive, but it's the only
464                  * way to make sure that you can't send a sigurg to
465                  * another process.
466                  */
467                 if (!suser() && current->pgrp != -arg &&
468                                 current->pid != arg) return(-EPERM);
469                 sk->proc = arg;
470                 return(0);
471         case F_GETOWN:
472                 return(sk->proc);
473         default:
474                 return(-EINVAL);
475   }
476 }
477 
478 /*
479  *      Set socket options on an inet socket.
480  */
481  
482 static int inet_setsockopt(struct socket *sock, int level, int optname,
483                     char *optval, int optlen)
484 {
485         struct sock *sk = (struct sock *) sock->data;  
486         if (level == SOL_SOCKET)
487                 return sock_setsockopt(sk,level,optname,optval,optlen);
488         if (sk->prot->setsockopt==NULL)
489                 return(-EOPNOTSUPP);
490         else
491                 return sk->prot->setsockopt(sk,level,optname,optval,optlen);
492 }
493 
494 
495 
496 
497 static int inet_getsockopt(struct socket *sock, int level, int optname,
498                     char *optval, int *optlen)
499 {
500         struct sock *sk = (struct sock *) sock->data;   
501         if (level == SOL_SOCKET) 
502                 return sock_getsockopt(sk,level,optname,optval,optlen);
503         if(sk->prot->getsockopt==NULL)          
504                 return(-EOPNOTSUPP);
505         else
506                 return sk->prot->getsockopt(sk,level,optname,optval,optlen);
507 }
508 
509 /*
510  *      This is meant for all protocols to use and covers goings on
511  *      at the socket level. Everything here is generic.
512  */
513 
514 int sock_setsockopt(struct sock *sk, int level, int optname,
515                 char *optval, int optlen)
516 {
517         int val;
518         int err;
519         struct linger ling;
520 
521         if (optval == NULL) 
522                 return(-EINVAL);
523 
524         err=verify_area(VERIFY_READ, optval, sizeof(int));
525         if(err)
526                 return err;
527         
528         val = get_fs_long((unsigned long *)optval);
529         switch(optname) 
530         {
531                 case SO_TYPE:
532                 case SO_ERROR:
533                         return(-ENOPROTOOPT);
534 
535                 case SO_DEBUG:  
536                         sk->debug=val?1:0;
537                 case SO_DONTROUTE:      /* Still to be implemented */
538                         return(0);
539                 case SO_BROADCAST:
540                         sk->broadcast=val?1:0;
541                         return 0;
542                 case SO_SNDBUF:
543                         if(val>32767)
544                                 val=32767;
545                         if(val<256)
546                                 val=256;
547                         sk->sndbuf=val;
548                         return 0;
549                 case SO_LINGER:
550                         err=verify_area(VERIFY_READ,optval,sizeof(ling));
551                         if(err)
552                                 return err;
553                         memcpy_fromfs(&ling,optval,sizeof(ling));
554                         if(ling.l_onoff==0)
555                                 sk->linger=0;
556                         else
557                         {
558                                 sk->lingertime=ling.l_linger;
559                                 sk->linger=1;
560                         }
561                         return 0;
562                 case SO_RCVBUF:
563                         if(val>32767)
564                                 val=32767;
565                         if(val<256)
566                                 val=256;
567                         sk->rcvbuf=val;
568                         return(0);
569 
570                 case SO_REUSEADDR:
571                         if (val) 
572                                 sk->reuse = 1;
573                         else 
574                                 sk->reuse = 0;
575                         return(0);
576 
577                 case SO_KEEPALIVE:
578                         if (val)
579                                 sk->keepopen = 1;
580                         else 
581                                 sk->keepopen = 0;
582                         return(0);
583 
584                 case SO_OOBINLINE:
585                         if (val) 
586                                 sk->urginline = 1;
587                         else 
588                                 sk->urginline = 0;
589                         return(0);
590 
591                 case SO_NO_CHECK:
592                         if (val) 
593                                 sk->no_check = 1;
594                         else 
595                                 sk->no_check = 0;
596                         return(0);
597 
598                  case SO_PRIORITY:
599                         if (val >= 0 && val < DEV_NUMBUFFS) 
600                         {
601                                 sk->priority = val;
602                         } 
603                         else 
604                         {
605                                 return(-EINVAL);
606                         }
607                         return(0);
608 
609                 default:
610                         return(-ENOPROTOOPT);
611         }
612 }
613 
614 
615 int sock_getsockopt(struct sock *sk, int level, int optname,
616                    char *optval, int *optlen)
617 {               
618         int val;
619         int err;
620         struct linger ling;
621 
622         switch(optname) 
623         {
624                 case SO_DEBUG:          
625                         val = sk->debug;
626                         break;
627                 
628                 case SO_DONTROUTE:      /* One last option to implement */
629                         val = 0;
630                         break;
631                 
632                 case SO_BROADCAST:
633                         val= sk->broadcast;
634                         break;
635                 
636                 case SO_LINGER: 
637                         err=verify_area(VERIFY_WRITE,optval,sizeof(ling));
638                         if(err)
639                                 return err;
640                         err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
641                         if(err)
642                                 return err;
643                         put_fs_long(sizeof(ling),(unsigned long *)optlen);
644                         ling.l_onoff=sk->linger;
645                         ling.l_linger=sk->lingertime;
646                         memcpy_tofs(optval,&ling,sizeof(ling));
647                         return 0;
648                 
649                 case SO_SNDBUF:
650                         val=sk->sndbuf;
651                         break;
652                 
653                 case SO_RCVBUF:
654                         val =sk->rcvbuf;
655                         break;
656 
657                 case SO_REUSEADDR:
658                         val = sk->reuse;
659                         break;
660 
661                 case SO_KEEPALIVE:
662                         val = sk->keepopen;
663                         break;
664 
665                 case SO_TYPE:
666                         if (sk->prot == &tcp_prot) 
667                                 val = SOCK_STREAM;
668                         else 
669                                 val = SOCK_DGRAM;
670                         break;
671 
672                 case SO_ERROR:
673                         val = sk->err;
674                         sk->err = 0;
675                         break;
676 
677                 case SO_OOBINLINE:
678                         val = sk->urginline;
679                         break;
680         
681                 case SO_NO_CHECK:
682                         val = sk->no_check;
683                         break;
684 
685                 case SO_PRIORITY:
686                         val = sk->priority;
687                         break;
688 
689                 default:
690                         return(-ENOPROTOOPT);
691         }
692         err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
693         if(err)
694                 return err;
695         put_fs_long(sizeof(int),(unsigned long *) optlen);
696 
697         err=verify_area(VERIFY_WRITE, optval, sizeof(int));
698         if(err)
699                 return err;
700         put_fs_long(val,(unsigned long *)optval);
701 
702         return(0);
703 }
704 
705 
706 
707 
708 static int
709 inet_listen(struct socket *sock, int backlog)
710 {
711   struct sock *sk;
712 
713   sk = (struct sock *) sock->data;
714   if (sk == NULL) {
715         printk("Warning: sock->data = NULL: %d\n" ,__LINE__);
716         return(0);
717   }
718 
719   /* We may need to bind the socket. */
720   if (sk->num == 0) {
721         sk->num = get_new_socknum(sk->prot, 0);
722         if (sk->num == 0) return(-EAGAIN);
723         put_sock(sk->num, sk);
724         sk->dummy_th.source = ntohs(sk->num);
725   }
726 
727   /* We might as well re use these. */ 
728   sk->max_ack_backlog = backlog;
729   if (sk->state != TCP_LISTEN) {
730         sk->ack_backlog = 0;
731         sk->state = TCP_LISTEN;
732   }
733   return(0);
734 }
735 
736 /*
737  *      Default callbacks for user INET sockets. These just wake up
738  *      the user owning the socket.
739  */
740 
741 static void def_callback1(struct sock *sk)
742 {
743         if(!sk->dead)
744                 wake_up_interruptible(sk->sleep);
745 }
746 
747 static void def_callback2(struct sock *sk,int len)
748 {
749         if(!sk->dead)
750                 wake_up_interruptible(sk->sleep);
751 }
752 
753 
754 static int
755 inet_create(struct socket *sock, int protocol)
756 {
757   struct sock *sk;
758   struct proto *prot;
759   int err;
760 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -