Esempio n. 1
0
/* Now we will only be called whenever we need to do
 * something, but we must be sure to process all of the
 * sockets that need it.
 */
void net_timer (unsigned long data)
{
	struct sock *sk = (struct sock*)data;
	int why = sk->timeout;

	/* Only process if socket is not in use. */
	if (atomic_read(&sk->sock_readers)) {
		/* Try again later. */ 
		mod_timer(&sk->timer, jiffies+HZ/20);
		return;
	}

	/* Always see if we need to send an ack. */
	if (sk->tp_pinfo.af_tcp.delayed_acks && !sk->zapped) {
		sk->prot->read_wakeup (sk);
		if (!sk->dead)
			sk->data_ready(sk,0);
	}

	/* Now we need to figure out why the socket was on the timer. */
	switch (why) {
		case TIME_DONE:
			/* If the socket hasn't been closed off, re-try a bit later. */
			if (!sk->dead) {
				net_reset_timer(sk, TIME_DONE, TCP_DONE_TIME);
				break;
			}

			if (sk->state != TCP_CLOSE) {
				printk (KERN_DEBUG "non CLOSE socket in time_done\n");
				break;
			}
			destroy_sock (sk);
			break;

		case TIME_DESTROY:
			/* We've waited for a while for all the memory associated with
			 * the socket to be freed.
			 */
			destroy_sock(sk);
			break;

		case TIME_CLOSE:
			/* We've waited long enough, close the socket. */
			tcp_set_state(sk, TCP_CLOSE);
			sk->shutdown = SHUTDOWN_MASK;
			if (!sk->dead)
				sk->state_change(sk);
			net_reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
			break;

		default:
			/* I want to see these... */
			printk ("net_timer: timer expired - reason %d is unknown\n", why);
			break;
	}
}
Esempio n. 2
0
static void packet_close(struct sock *sk, unsigned long timeout)
{
	/*
	 *	Stop more data and kill the socket off.
	 */

	lock_sock(sk);
	sk->state = TCP_CLOSE;

	/*
	 *	Unhook the notifier
	 */

	unregister_netdevice_notifier(&sk->protinfo.af_packet.notifier);

	if(sk->protinfo.af_packet.prot_hook)
	{
		/*
		 *	Remove the protocol hook
		 */
		 
		dev_remove_pack((struct packet_type *)sk->protinfo.af_packet.prot_hook);

		/*
		 *	Dispose of litter carefully.
		 */
	 
		kfree_s((void *)sk->protinfo.af_packet.prot_hook, sizeof(struct packet_type));
		sk->protinfo.af_packet.prot_hook = NULL;
	}
	
	release_sock(sk);
	destroy_sock(sk);
}
Esempio n. 3
0
static int
ip_proto_accept (struct socket *sock, struct socket *newsock, int flags)
{
  volatile struct sock *sk1, *sk2;
  sk1= sock->data;
   if (sk1 == NULL)
     {
	printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
	return (0);
     }
  newsock->data = NULL;
  if (sk1->prot->accept == NULL) return (-EOPNOTSUPP);
  /* restore the state if we have been interrupted, and
     then returned. */
  if (sk1->pair != NULL )
    {
      sk2 = sk1->pair;
      sk1->pair = NULL;
    }
  else
    {
      sk2 = sk1->prot->accept (sk1,flags);
      if (sk2 == NULL)
	return (-sk1->err);
    }
  newsock->data = (void *)sk2;
  sk2->sleep = (void *)newsock->wait;
  newsock->conn = NULL;
  if (flags & O_NONBLOCK)
    return (0);

  cli(); /* avoid the race. */
  while (sk2->state == TCP_SYN_RECV)
    {
      interruptible_sleep_on (sk2->sleep);
      if (current->signal & ~current->blocked)
	{
	   sti();
	   sk1->pair = sk2;
	   sk2->sleep = NULL;
	   newsock->data = NULL;
	   return (-ERESTARTSYS);
	}
    }
  sti();

  if (sk2->state != TCP_ESTABLISHED && sk2->err)
    {
      int err;
      err = -sk2->err;
      destroy_sock (sk2);
      newsock->data = NULL;
      return (err);
    }
  newsock->state = SS_CONNECTED;
  return (0);
}
Esempio n. 4
0
static void udp_close(struct sock *sk, unsigned long timeout)
{
	lock_sock(sk);
	sk->state = TCP_CLOSE;
	sk->dead = 1;
	release_sock(sk);
	udp_v4_unhash(sk);
	destroy_sock(sk);
}
Esempio n. 5
0
static void raw_close(struct sock *sk, unsigned long timeout)
{
	sk->state = TCP_CLOSE;
#ifdef CONFIG_IP_MROUTE	
	if(sk==mroute_socket)
	{
		mroute_close(sk);
		mroute_socket=NULL;
	}
#endif	
	destroy_sock(sk);
}
Esempio n. 6
0
static int inet_create(struct socket *sock, int protocol)
{
	struct sock *sk;
	struct proto *prot;
	int err;

	sk = (struct sock *) kmalloc(sizeof(*sk), GFP_KERNEL);
	if (sk == NULL) 
		return(-ENOBUFS);
	
	sk->num = 0;
	sk->reuse = 0;
	
	switch(sock->type) 
	{
		case SOCK_STREAM:
		case SOCK_SEQPACKET:
			if (protocol && protocol != IPPROTO_TCP) 
			{
				kfree_s((void *)sk, sizeof(*sk));
				return(-EPROTONOSUPPORT);
			}
			protocol = IPPROTO_TCP;
			/* TCP_NO_CHECK tcp协议全局默认值	*/
			sk->no_check = TCP_NO_CHECK;
			prot = &tcp_prot;
			break;

		case SOCK_DGRAM:
			if (protocol && protocol != IPPROTO_UDP) 
			{
				kfree_s((void *)sk, sizeof(*sk));
				return(-EPROTONOSUPPORT);
			}
			protocol = IPPROTO_UDP;
			sk->no_check = UDP_NO_CHECK;
			prot=&udp_prot;
			break;
      
		case SOCK_RAW:
			if (!suser()) 
			{
				kfree_s((void *)sk, sizeof(*sk));
				return(-EPERM);
			}
			if (!protocol) 
			{
				kfree_s((void *)sk, sizeof(*sk));
				return(-EPROTONOSUPPORT);
			}
			prot = &raw_prot;
			sk->reuse = 1;
			sk->no_check = 0;	/*
						 * Doesn't matter no checksum is
						 * performed anyway.
						 */
			sk->num = protocol;
			break;

		case SOCK_PACKET:
			if (!suser()) 
			{
				kfree_s((void *)sk, sizeof(*sk));
				return(-EPERM);
			}
			if (!protocol) 
			{
				kfree_s((void *)sk, sizeof(*sk));
				return(-EPROTONOSUPPORT);
			}
			prot = &packet_prot;
			sk->reuse = 1;
			sk->no_check = 0;	/* Doesn't matter no checksum is
						 * performed anyway.
						 */
			sk->num = protocol;
			break;

		default:
			kfree_s((void *)sk, sizeof(*sk));
			return(-ESOCKTNOSUPPORT);
	}
	
	sk->socket = sock;
#ifdef CONFIG_TCP_NAGLE_OFF
	sk->nonagle = 1;
#else    
	sk->nonagle = 0;
#endif  
	sk->type = sock->type;
	sk->stamp.tv_sec=0;
	sk->protocol = protocol;		// 传输层协议值
	sk->wmem_alloc = 0;
	sk->rmem_alloc = 0;
	sk->sndbuf = SK_WMEM_MAX;	// 初始化该链接的最大写缓冲区
	sk->rcvbuf = SK_RMEM_MAX;	// 初始化该链接的最大读缓冲区
	sk->pair = NULL;
	sk->opt = NULL;
	sk->write_seq = 0;
	sk->acked_seq = 0;
	sk->copied_seq = 0;
	sk->fin_seq = 0;
	sk->urg_seq = 0;
	sk->urg_data = 0;
	sk->proc = 0;
	sk->rtt = 0;				/*TCP_WRITE_TIME << 3;*/
	sk->rto = TCP_TIMEOUT_INIT;		/*TCP_WRITE_TIME*/
	sk->mdev = 0;
	sk->backoff = 0;
	sk->packets_out = 0;
	sk->cong_window = 1;		 /* start with only sending one packet at a time. 
							  * 拥塞窗口设置为1,即tcp首先进入慢启动状态	*/
	sk->cong_count = 0;
	sk->ssthresh = 0;
	sk->max_window = 0;
	sk->urginline = 0;
	sk->intr = 0;
	sk->linger = 0;
	sk->destroy = 0;
	sk->priority = 1;
	sk->shutdown = 0;
	sk->keepopen = 0;
	sk->zapped = 0;
	sk->done = 0;
	sk->ack_backlog = 0;
	sk->window = 0;
	sk->bytes_rcv = 0;
	sk->state = TCP_CLOSE;	// 本地初创socket,状态是关闭状态
	sk->dead = 0;
	sk->ack_timed = 0;
	sk->partial = NULL;
	sk->user_mss = 0;
	sk->debug = 0;

	/* 最大可暂缓应答的数据字节数	*/
	/* this is how many unacked bytes we will accept for this socket.  */
	sk->max_unacked = 2048; /* needs to be at most 2 full packets. */

	/* 已发送但未收到确认的数据报个数上限	*/
	/* how many packets we should send before forcing an ack. 
	   if this is set to zero it is the same as sk->delay_acks = 0 */
	sk->max_ack_backlog = 0;
	sk->inuse = 0;
	sk->delay_acks = 0;
	skb_queue_head_init(&sk->write_queue);
	skb_queue_head_init(&sk->receive_queue);
	sk->mtu = 576;		// mtu设置成保守的576,该大小在绝大多数连接上不会造成碎片
	sk->prot = prot;
	sk->sleep = sock->wait;
	sk->daddr = 0;
	sk->saddr = 0 /* ip_my_addr() */;
	sk->err = 0;
	sk->next = NULL;
	sk->pair = NULL;
	sk->send_tail = NULL;
	sk->send_head = NULL;
	sk->timeout = 0;
	sk->broadcast = 0;
	sk->localroute = 0;
	init_timer(&sk->timer);
	init_timer(&sk->retransmit_timer);
	sk->timer.data = (unsigned long)sk;
	sk->timer.function = &net_timer;
	skb_queue_head_init(&sk->back_log);
	sk->blog = 0;
	sock->data =(void *) sk;
	sk->dummy_th.doff = sizeof(sk->dummy_th)/4;
	sk->dummy_th.res1=0;
	sk->dummy_th.res2=0;
	sk->dummy_th.urg_ptr = 0;
	sk->dummy_th.fin = 0;
	sk->dummy_th.syn = 0;
	sk->dummy_th.rst = 0;
	sk->dummy_th.psh = 0;
	sk->dummy_th.ack = 0;
	sk->dummy_th.urg = 0;
	sk->dummy_th.dest = 0;
	sk->ip_tos=0;
	sk->ip_ttl=64;
#ifdef CONFIG_IP_MULTICAST
	sk->ip_mc_loop=1;
	sk->ip_mc_ttl=1;
	*sk->ip_mc_name=0;
	sk->ip_mc_list=NULL;
#endif
  	
	sk->state_change = def_callback1;
	sk->data_ready = def_callback2;
	sk->write_space = def_callback3;
	sk->error_report = def_callback1;

	if (sk->num) 
	{
	/*
	 * It assumes that any protocol which allows
	 * the user to assign a number at socket
	 * creation time automatically
	 * shares.
	 */
		put_sock(sk->num, sk);
		sk->dummy_th.source = ntohs(sk->num);
	}

	if (sk->prot->init) 
	{
		err = sk->prot->init(sk);
		if (err != 0) 
		{
			destroy_sock(sk);
			return(err);
		}
	}
	return(0);
}
Esempio n. 7
0
static int inet_accept(struct socket *sock, struct socket *newsock, int flags)
{
	struct sock *sk1, *sk2;
	int err;

	/* sk1指向监听套接字的sk结构 */
	sk1 = (struct sock *) sock->data;

	/*
	 * We've been passed an extra socket.
	 * We need to free it up because the tcp module creates
	 * its own when it accepts one.
	 */
	if (newsock->data)
	{
	  	struct sock *sk=(struct sock *)newsock->data;
	  	newsock->data=NULL;
	  	sk->dead = 1;
	  	destroy_sock(sk);
	}
  
	if (sk1->prot->accept == NULL) 
		return(-EOPNOTSUPP);

	/* Restore the state if we have been interrupted, and then returned. */
	/* sk->pair中存放上次被信号打断的accpet过程中取出的连接请求 */
	if (sk1->pair != NULL ) 
	{
		sk2 = sk1->pair;
		sk1->pair = NULL;
	} 
	else
	{
		sk2 = sk1->prot->accept(sk1,flags);
		if (sk2 == NULL) 
		{
			if (sk1->err <= 0)
				printk("Warning sock.c:sk1->err <= 0.  Returning non-error.\n");
			err=sk1->err;
			sk1->err=0;
			return(-err);
		}
	}
	// 执行到这里:已经从请求队列中取出一个请求
	
	newsock->data = (void *)sk2;
	sk2->sleep = newsock->wait;
	sk2->socket = newsock;
	newsock->conn = NULL;	// INET域中,该字段为NULL
	
	if (flags & O_NONBLOCK) 	// 非阻塞accpet可能会返回尚未established的连接
		return(0);			// 区别与尾端返回的不同,在尾端返回处设置newsock->state = SS_CONNECTED

	cli(); /* avoid the race. */	
	while(sk2->state == TCP_SYN_RECV) 	// 等待连接完成
	{
		interruptible_sleep_on(sk2->sleep);
		if (current->signal & ~current->blocked) 
		{
			sti();
			sk1->pair = sk2;			// 如果被信号打断,就把已经取出来的连接请求放入sk->pair中暂存
			sk2->sleep = NULL;
			sk2->socket=NULL;
			newsock->data = NULL;
			return(-ERESTARTSYS);
		}
	}
	sti();

	if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) 	// 接收过程出错
	{
		err = -sk2->err;
		sk2->err=0;
		sk2->dead=1;	/* ANK */
		destroy_sock(sk2);
		newsock->data = NULL;
		return(err);
	}
	newsock->state = SS_CONNECTED;
	return(0);
}
Esempio n. 8
0
static int inet6_create(struct socket *sock, int protocol)
{
	struct sock *sk;
	struct proto *prot;

	sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
	if (sk == NULL) 
		goto do_oom;

	if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) {
		if (protocol && protocol != IPPROTO_TCP) 
			goto free_and_noproto;
		protocol = IPPROTO_TCP;
		prot = &tcpv6_prot;
		sock->ops = &inet6_stream_ops;
	} else if(sock->type == SOCK_DGRAM) {
		if (protocol && protocol != IPPROTO_UDP) 
			goto free_and_noproto;
		protocol = IPPROTO_UDP;
		sk->no_check = UDP_NO_CHECK;
		prot=&udpv6_prot;
		sock->ops = &inet6_dgram_ops;
	} else if(sock->type == SOCK_RAW) {
		if (!capable(CAP_NET_RAW))
			goto free_and_badperm;
		if (!protocol) 
			goto free_and_noproto;
		prot = &rawv6_prot;
		sock->ops = &inet6_dgram_ops;
		sk->reuse = 1;
		sk->num = protocol;
	} else {
		goto free_and_badtype;
	}
	
	sock_init_data(sock, sk);

	sk->destruct            = NULL;
	sk->zapped		= 0;
	sk->family		= PF_INET6;
	sk->protocol		= protocol;

	sk->prot		= prot;
	sk->backlog_rcv		= prot->backlog_rcv;

	sk->timer.data		= (unsigned long)sk;
	sk->timer.function	= &net_timer;

	sk->net_pinfo.af_inet6.hop_limit  = -1;
	sk->net_pinfo.af_inet6.mcast_hops = -1;
	sk->net_pinfo.af_inet6.mc_loop	  = 1;
	sk->net_pinfo.af_inet6.pmtudisc	  = IPV6_PMTUDISC_WANT;

	/* Init the ipv4 part of the socket since we can have sockets
	 * using v6 API for ipv4.
	 */
	sk->ip_ttl	= 64;

	sk->ip_mc_loop	= 1;
	sk->ip_mc_ttl	= 1;
	sk->ip_mc_index	= 0;
	sk->ip_mc_list	= NULL;

	if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW)
		sk->ip_hdrincl=1;

	if (sk->num) {
		/* It assumes that any protocol which allows
		 * the user to assign a number at socket
		 * creation time automatically shares.
		 */
		sk->sport = ntohs(sk->num);
		sk->prot->hash(sk);
		add_to_prot_sklist(sk);
	}

	if (sk->prot->init) {
		int err = sk->prot->init(sk);
		if (err != 0) {
			destroy_sock(sk);
			return(err);
		}
	}
	MOD_INC_USE_COUNT;
	return(0);

free_and_badtype:
	sk_free(sk);
	return -ESOCKTNOSUPPORT;
free_and_badperm:
	sk_free(sk);
	return -EPERM;
free_and_noproto:
	sk_free(sk);
	return -EPROTONOSUPPORT;
do_oom:
	return -ENOBUFS;
}
Esempio n. 9
0
static int
ip_proto_create (struct socket *sock, int protocol)
{
  volatile struct sock *sk;
  struct proto *prot;
  int err;

  sk = malloc (sizeof (*sk));
  if (sk == NULL)
    return (-ENOMEM);
  sk->num = 0;


  switch (sock->type)
    {
    case SOCK_STREAM:
    case SOCK_SEQPACKET:
       if (protocol && protocol != IP_TCP)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       sk->no_check = TCP_NO_CHECK;
       prot = &tcp_prot;
       break;

    case SOCK_DGRAM:
       if (protocol && protocol != IP_UDP)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       sk->no_check = UDP_NO_CHECK;
       prot=&udp_prot;
       break;
      
     case SOCK_RAW:
       if (!suser())
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPERM);
	 }

       if (!protocol)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       prot = &raw_prot;
       sk->reuse = 1;
       sk->no_check = 0; /* doesn't matter no checksum is preformed
			    anyway. */
       sk->num = protocol;
       break;

    case SOCK_PACKET:
       if (!suser())
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPERM);
	 }

       if (!protocol)
	 {
	    free_s ((void *)sk, sizeof (*sk));
	    return (-EPROTONOSUPPORT);
	 }
       prot = &packet_prot;
       sk->reuse = 1;
       sk->no_check = 0; /* doesn't matter no checksum is preformed
			    anyway. */
       sk->num = protocol;
       break;

      
    default:
       free_s ((void *)sk, sizeof (*sk));
       return (-ESOCKTNOSUPPORT);

    }
  sk->protocol = protocol;
  sk->wmem_alloc = 0;
  sk->rmem_alloc = 0;
  sk->pair = NULL;
  sk->opt = NULL;
  sk->send_seq = 0;
  sk->acked_seq = 0;
  sk->copied_seq = 0;
  sk->fin_seq = 0;
  sk->proc = 0;
  sk->rtt = TCP_WRITE_TIME;
  sk->packets_out = 0;
  sk->cong_window = 1; /* start with only sending one packet at a time. */
  sk->exp_growth = 1;  /* if set cong_window grow exponentially every time
			  we get an ack. */
  sk->urginline = 0;
  sk->intr = 0;
  sk->linger = 0;
  sk->destroy = 0;
  sk->reuse = 0;
  sk->priority = 1;
  sk->shutdown = 0;
  sk->urg = 0;
  sk->keepopen = 0;
  sk->done = 0;
  sk->ack_backlog = 0;
  sk->window = 0;
  sk->bytes_rcv = 0;
  sk->state = TCP_CLOSE;
  sk->dead = 0;
  sk->ack_timed = 0;

  /* this is how many unacked bytes we will accept for
     this socket.  */

  sk->max_unacked = 2048; /* needs to be at most 2 full packets. */

  /* how many packets we should send before forcing an ack. 
     if this is set to zero it is the same as sk->delay_acks = 0 */

  sk->max_ack_backlog = MAX_ACK_BACKLOG;
  sk->inuse = 0;
  sk->delay_acks = 1; /* default to waiting a while before sending
			 acks.  */
  sk->wback = NULL;
  sk->wfront = NULL;
  sk->rqueue = NULL;
  sk->mtu = 576;
  sk->prot = prot;
  sk->sleep = sock->wait;
  sk->daddr = 0;
  sk->saddr = MY_IP_ADDR;
  sk->err = 0;
  sk->next = NULL;
  sk->pair = NULL;
  sk->send_tail = NULL;
  sk->send_head = NULL;
  sk->time_wait.len = TCP_CONNECT_TIME;
  sk->time_wait.when = 0;
  sk->time_wait.sk = sk;
  sk->time_wait.next = NULL;
  sk->timeout = 0;
  sk->back_log = NULL;
  sk->blog = 0;
  sock->data =(void *) sk;
  sk->dummy_th.doff = sizeof (sk->dummy_th)/4;
  sk->dummy_th.res1=0;
  sk->dummy_th.res2=0;
  sk->dummy_th.urg_ptr = 0;
  sk->dummy_th.fin = 0;
  sk->dummy_th.syn = 0;
  sk->dummy_th.rst = 0;
  sk->dummy_th.psh = 0;
  sk->dummy_th.ack = 0;
  sk->dummy_th.urg = 0;
  sk->dummy_th.dest = 0;
  if (sk->num)
    {
       put_sock (sk->num, sk);
    }
  else
    {
       sk->num = get_new_socknum(sk->prot, 0);
    }
  /* make sure there was a free socket. */
  if (sk->num == 0)
    {
      destroy_sock(sk);
      return (-EAGAIN);
    }
  put_sock(sk->num, sk);
  sk->dummy_th.source = net16(sk->num);
  if (sk->prot->init)
    {
       err = sk->prot->init(sk);
       if (err != 0)
	 {
	    destroy_sock (sk);
	    return (err);
	 }
    }
  return (0);
}
Esempio n. 10
0
/* 每个struct sock的时钟函数 */
void
net_timer (unsigned long data)
{
  struct sock *sk = (struct sock*)data;
  /* 相当于获取时钟的类型吧, */
  int why = sk->timeout;
  /* timeout is overwritten by 'delete_timer' and 'reset_timer' */

  /* 判断sock是否已被其他进程使用,或者当前是否正在执行网络的下半部分,
    * 如果当前正在执行网络的下半部分,则重新设置sock的timer,同时添加到
    * 内核时钟当中,等待下次执行 
    */
  if (sk->inuse || in_inet_bh()) {
    sk->timer.expires = 10;
    add_timer(&sk->timer);
    return;
  }

  /* 设置sock为用 */
  sk->inuse = 1;

  DPRINTF ((DBG_TMR, "net_timer: found sk=%X why = %d\n", sk, why));
  if (sk->wfront && 
      before(sk->window_seq, sk->wfront->h.seq) &&
      sk->send_head == NULL &&
      sk->ack_backlog == 0 &&
      sk->state != TCP_TIME_WAIT)
    reset_timer(sk, TIME_PROBE0, sk->rto);
  else if (sk->keepopen)
    reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);

  /* Always see if we need to send an ack. */
  /* 看看还有没有收到的数据包没有应答 */
  if (sk->ack_backlog) {
    /* sock发送确认数据包*/
    sk->prot->read_wakeup (sk);
    if (! sk->dead)
      wake_up_interruptible (sk->sleep);
  }

  /* Now we need to figure out why the socket was on the timer. */
  switch (why) {
    case TIME_DONE:
	if (! sk->dead || sk->state != TCP_CLOSE) {
	  printk ("non dead socket in time_done\n");
	  release_sock (sk);
	  break;
	}
	destroy_sock (sk);
	break;
    case TIME_DESTROY:
	/* We've waited for a while for all the memory associated with
	 * the socket to be freed.  We need to print an error message.
	 */
	/* 如果sock的发送缓冲区和接收缓冲区都为空,则直接在后面的语句当中释放 */
	if(sk->wmem_alloc!=0 || sk->rmem_alloc!=0)
	{
		DPRINTF ((DBG_TMR, "possible memory leak.  sk = %X\n", sk));
		sk->wmem_alloc++;	/* So it DOESNT go away */
		destroy_sock (sk);
		sk->wmem_alloc--;	/* Might now have hit 0 - fall through and do it again if so */
		sk->inuse = 0;	/* This will be ok, the destroy won't totally work */
	}
	if(sk->wmem_alloc==0 && sk->rmem_alloc==0)
		destroy_sock(sk);	/* Socket gone, DONT update sk->inuse! */
	break;
    case TIME_CLOSE:
	/* We've waited long enough, close the socket. */
	sk->state = TCP_CLOSE;
	delete_timer (sk);
	/* Kill the ARP entry in case the hardware has changed. */
	arp_destroy_maybe (sk->daddr);
	if (!sk->dead)
	  wake_up_interruptible (sk->sleep);
	sk->shutdown = SHUTDOWN_MASK;
	reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME);
	release_sock (sk);
	break;
    case TIME_PROBE0:   /* 窗口探测定时器,也被称为坚持定时器 */
	tcp_send_probe0(sk);
	release_sock (sk);
	break;
    case TIME_WRITE:	/* 超时重传定时器 */   /* try to retransmit. */
	/* It could be we got here because we needed to send an ack.
	 * So we need to check for that.
	 */
	if (sk->send_head) {
	  if (jiffies < (sk->send_head->when + sk->rto)) {
	    reset_timer (sk, TIME_WRITE, 
			 (sk->send_head->when + sk->rto - jiffies));
	    release_sock (sk);
	    break;
	  }
	  /* printk("timer: seq %d retrans %d out %d cong %d\n", sk->send_head->h.seq,
	     sk->retransmits, sk->packets_out, sk->cong_window); */
	  DPRINTF ((DBG_TMR, "retransmitting.\n"));
          /* 调用tcp协议的超时重传函数 */
	  sk->prot->retransmit (sk, 0);
	  if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
	    || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) {
	    DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 1\n"));
	    arp_destroy_maybe (sk->daddr);
	    ip_route_check (sk->daddr);
	  }
	  if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) {
	    DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 2\n"));
	    sk->err = ETIMEDOUT;
	    if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2
	      || sk->state == TCP_LAST_ACK) {
	      sk->state = TCP_TIME_WAIT;
	      reset_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
	    } else {
	      sk->prot->close (sk, 1);
	      break;
	    }
	  }
	}
	release_sock (sk);
	break;
    case TIME_KEEPOPEN:          /* 保活定时器 */
	/* Send something to keep the connection open. */
	if (sk->prot->write_wakeup)
	  sk->prot->write_wakeup (sk);
	sk->retransmits++;  /* 因为是重发定时,所以会增加超时重发次数 */
	if (sk->shutdown == SHUTDOWN_MASK) {
	  sk->prot->close (sk, 1);
	  sk->state = TCP_CLOSE;
	}

	if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
	  || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) {
	  DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 1\n"));
	  arp_destroy_maybe (sk->daddr);
	  ip_route_check (sk->daddr);
	  release_sock (sk);
	  break;
	}
	if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) {
	  DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 2\n"));
	  arp_destroy_maybe (sk->daddr);
	  sk->err = ETIMEDOUT;
	  if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2) {
	    sk->state = TCP_TIME_WAIT;
	    if (!sk->dead)
	      wake_up_interruptible (sk->sleep);
	    release_sock (sk);
	  } else {
	    sk->prot->close (sk, 1);
	  }
	  break;
	}
	release_sock (sk);
	break;
    default:
	printk ("net timer expired - reason unknown, sk=%08X\n", (int)sk);
	release_sock (sk);
	break;
  }
}
Esempio n. 11
0
void net_timer (unsigned long data)
{
	struct sock *sk = (struct sock*)data;
	int why = sk->timeout;

	/* 
	 * only process if socket is not in use
	 */

	if (sk->users)
	{
		sk->timer.expires = jiffies+HZ;
		add_timer(&sk->timer);
		sti();
		return;
	}

	/* Always see if we need to send an ack. */

	if (sk->ack_backlog && !sk->zapped) 
	{
		sk->prot->read_wakeup (sk);
		if (! sk->dead)
		sk->data_ready(sk,0);
	}

	/* Now we need to figure out why the socket was on the timer. */

	switch (why) 
	{
		case TIME_DONE:
			/* If the socket hasn't been closed off, re-try a bit later */
			if (!sk->dead) {
				reset_timer(sk, TIME_DONE, TCP_DONE_TIME);
				break;
			}

			if (sk->state != TCP_CLOSE) 
			{
				printk ("non CLOSE socket in time_done\n");
				break;
			}
			destroy_sock (sk);
			break;

		case TIME_DESTROY:
		/*
		 *	We've waited for a while for all the memory associated with
		 *	the socket to be freed.
		 */

			destroy_sock(sk);
			break;

		case TIME_CLOSE:
			/* We've waited long enough, close the socket. */
			sk->state = TCP_CLOSE;
			delete_timer (sk);
			if (!sk->dead)
				sk->state_change(sk);
			sk->shutdown = SHUTDOWN_MASK;
			reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
			break;

		default:
			printk ("net_timer: timer expired - reason %d is unknown\n", why);
			break;
	}
}
Esempio n. 12
0
static int inet_accept(struct socket *sock, struct socket *newsock, int flags)
{
	struct sock *sk1, *sk2;
	int err;

	sk1 = (struct sock *) sock->data;

	/*
	 * We've been passed an extra socket.
	 * We need to free it up because the tcp module creates
	 * its own when it accepts one.
	 */
	if (newsock->data)
	{
	  	struct sock *sk=(struct sock *)newsock->data;
	  	newsock->data=NULL;
	  	sk->dead = 1;
	  	destroy_sock(sk);
	}
  
	if (sk1->prot->accept == NULL) 
		return(-EOPNOTSUPP);

	/* Restore the state if we have been interrupted, and then returned. */
	if (sk1->pair != NULL ) 
	{
		sk2 = sk1->pair;
		sk1->pair = NULL;
	} 
	else
	{
		sk2 = sk1->prot->accept(sk1,flags);
		if (sk2 == NULL) 
		{
			if (sk1->err <= 0)
				printk("Warning sock.c:sk1->err <= 0.  Returning non-error.\n");
			err=sk1->err;
			sk1->err=0;
			return(-err);
		}
	}
	newsock->data = (void *)sk2;
	sk2->sleep = newsock->wait;
	sk2->socket = newsock;
	newsock->conn = NULL;
	if (flags & O_NONBLOCK) 
		return(0);

	cli(); /* avoid the race. */
	while(sk2->state == TCP_SYN_RECV) 
	{
		interruptible_sleep_on(sk2->sleep);
		if (current->signal & ~current->blocked) 
		{
			sti();
			sk1->pair = sk2;
			sk2->sleep = NULL;
			sk2->socket=NULL;
			newsock->data = NULL;
			return(-ERESTARTSYS);
		}
	}
	sti();

	if (sk2->state != TCP_ESTABLISHED && sk2->err > 0) 
	{
		err = -sk2->err;
		sk2->err=0;
		sk2->dead=1;	/* ANK */
		destroy_sock(sk2);
		newsock->data = NULL;
		return(err);
	}
	newsock->state = SS_CONNECTED;
	return(0);
}