亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tcp.c

?? 內核是系統的心臟
?? C
?? 第 1 頁 / 共 5 頁
字號:

	/* If we didn't get any memory, we need to sleep. */
	if (skb == NULL) {
		if (nonblock /* || copied */) {
			release_sock(sk);
			DPRINTF((DBG_TCP, "tcp_write: return 4\n"));
			if (copied) return(copied);
			return(-EAGAIN);
		}

		/* FIXME: here is another race condition. */
		tmp = sk->wmem_alloc;
		release_sock(sk);
		cli();
		/* Again we will try to avoid it. */
		if (tmp <= sk->wmem_alloc &&
		  (sk->state == TCP_ESTABLISHED||sk->state == TCP_CLOSE_WAIT)
				&& sk->err == 0) {
			interruptible_sleep_on(sk->sleep);
			if (current->signal & ~current->blocked) {
				sti();
				DPRINTF((DBG_TCP, "tcp_write: return 5\n"));
				if (copied) return(copied);
				return(-ERESTARTSYS);
			}
		}
		sk->inuse = 1;
		sti();
		continue;
	}

	skb->len = 0;
	skb->sk = sk;
	skb->free = 0;

	buff = skb->data;

	/*
	 * FIXME: we need to optimize this.
	 * Perhaps some hints here would be good.
	 */
	tmp = prot->build_header(skb, sk->saddr, sk->daddr, &dev,
				 IPPROTO_TCP, sk->opt, skb->mem_len,sk->ip_tos,sk->ip_ttl);
	if (tmp < 0 ) {
		prot->wfree(sk, skb->mem_addr, skb->mem_len);
		release_sock(sk);
		DPRINTF((DBG_TCP, "tcp_write: return 6\n"));
		if (copied) return(copied);
		return(tmp);
	}
	skb->len += tmp;
	skb->dev = dev;
	buff += tmp;
	skb->h.th =(struct tcphdr *) buff;
	tmp = tcp_build_header((struct tcphdr *)buff, sk, len-copy);
	if (tmp < 0) {
		prot->wfree(sk, skb->mem_addr, skb->mem_len);
		release_sock(sk);
		DPRINTF((DBG_TCP, "tcp_write: return 7\n"));
		if (copied) return(copied);
		return(tmp);
	}

	if (flags & MSG_OOB) {
		((struct tcphdr *)buff)->urg = 1;
		((struct tcphdr *)buff)->urg_ptr = ntohs(copy);
	}
	skb->len += tmp;
	memcpy_fromfs(buff+tmp, from, copy);

	from += copy;
	copied += copy;
	len -= copy;
	skb->len += copy;
	skb->free = 0;
	sk->write_seq += copy;

	if (send_tmp != NULL && sk->packets_out) {
		tcp_enqueue_partial(send_tmp, sk);
		continue;
	}
	tcp_send_skb(sk, skb);
  }
  sk->err = 0;

/*
 *	Nagles rule. Turn Nagle off with TCP_NODELAY for highly
 *	interactive fast network servers. It's meant to be on and
 *	it really improves the throughput though not the echo time
 *	on my slow slip link - Alan
 */

  /* Avoid possible race on send_tmp - c/o Johannes Stille */
  if(sk->partial && 
     ((!sk->packets_out) 
     /* If not nagling we can send on the before case too.. */
      || (sk->nonagle && before(sk->write_seq , sk->window_seq))
      ))
  	tcp_send_partial(sk);
  /* -- */
  release_sock(sk);
  DPRINTF((DBG_TCP, "tcp_write: return 8\n"));
  return(copied);
}


static int
tcp_sendto(struct sock *sk, unsigned char *from,
	   int len, int nonblock, unsigned flags,
	   struct sockaddr_in *addr, int addr_len)
{
  struct sockaddr_in sin;

  if (addr_len < sizeof(sin)) return(-EINVAL);
  memcpy_fromfs(&sin, addr, sizeof(sin));
  if (sin.sin_family && sin.sin_family != AF_INET) return(-EINVAL);
  if (sin.sin_port != sk->dummy_th.dest) return(-EINVAL);
  if (sin.sin_addr.s_addr != sk->daddr) return(-EINVAL);
  return(tcp_write(sk, from, len, nonblock, flags));
}


static void
tcp_read_wakeup(struct sock *sk)
{
  int tmp;
  struct device *dev = NULL;
  struct tcphdr *t1;
  struct sk_buff *buff;

  DPRINTF((DBG_TCP, "in tcp read wakeup\n"));
  if (!sk->ack_backlog) return;

  /*
   * FIXME: we need to put code here to prevent this routine from
   * being called.  Being called once in a while is ok, so only check
   * if this is the second time in a row.
   */

  /*
   * We need to grab some memory, and put together an ack,
   * and then put it into the queue to be sent.
   */
  buff = sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
  if (buff == NULL) {
	/* Try again real soon. */
	reset_timer(sk, TIME_WRITE, 10);
	return;
  }

  buff->mem_addr = buff;
  buff->mem_len = MAX_ACK_SIZE;
  buff->len = sizeof(struct tcphdr);
  buff->sk = sk;

  /* Put in the IP header and routing stuff. */
  tmp = sk->prot->build_header(buff, sk->saddr, sk->daddr, &dev,
			       IPPROTO_TCP, sk->opt, MAX_ACK_SIZE,sk->ip_tos,sk->ip_ttl);
  if (tmp < 0) {
  	buff->free=1;
	sk->prot->wfree(sk, buff->mem_addr, buff->mem_len);
	return;
  }

  buff->len += tmp;
  t1 =(struct tcphdr *)(buff->data +tmp);

  memcpy(t1,(void *) &sk->dummy_th, sizeof(*t1));
  t1->seq = htonl(sk->sent_seq);
  t1->ack = 1;
  t1->res1 = 0;
  t1->res2 = 0;
  t1->rst = 0;
  t1->urg = 0;
  t1->syn = 0;
  t1->psh = 0;
  sk->ack_backlog = 0;
  sk->bytes_rcv = 0;
  sk->window = tcp_select_window(sk);/*sk->prot->rspace(sk);*/
  t1->window = ntohs(sk->window);
  t1->ack_seq = ntohl(sk->acked_seq);
  t1->doff = sizeof(*t1)/4;
  tcp_send_check(t1, sk->saddr, sk->daddr, sizeof(*t1), sk);
  sk->prot->queue_xmit(sk, dev, buff, 1);
}


/*
 * FIXME:
 * This routine frees used buffers.
 * It should consider sending an ACK to let the
 * other end know we now have a bigger window.
 */
static void
cleanup_rbuf(struct sock *sk)
{
  unsigned long flags;
  int left;
  struct sk_buff *skb;

  if(sk->debug)
  	printk("cleaning rbuf for sk=%p\n", sk);
  
  save_flags(flags);
  cli();
  
  left = sk->prot->rspace(sk);
 
  /*
   * We have to loop through all the buffer headers,
   * and try to free up all the space we can.
   */
  while((skb=skb_peek(&sk->rqueue)) != NULL ) 
  {
	if (!skb->used) 
		break;
	skb_unlink(skb);
	skb->sk = sk;
	kfree_skb(skb, FREE_READ);
  }

  restore_flags(flags);

  /*
   * FIXME:
   * At this point we should send an ack if the difference
   * in the window, and the amount of space is bigger than
   * TCP_WINDOW_DIFF.
   */
  DPRINTF((DBG_TCP, "sk->window left = %d, sk->prot->rspace(sk)=%d\n",
			sk->window - sk->bytes_rcv, sk->prot->rspace(sk)));

  if(sk->debug)
  	printk("sk->rspace = %lu, was %d\n", sk->prot->rspace(sk),
  					    left);
  if (sk->prot->rspace(sk) != left) 
  {
	/*
	 * This area has caused the most trouble.  The current strategy
	 * is to simply do nothing if the other end has room to send at
	 * least 3 full packets, because the ack from those will auto-
	 * matically update the window.  If the other end doesn't think
	 * we have much space left, but we have room for atleast 1 more
	 * complete packet than it thinks we do, we will send an ack
	 * immediatedly.  Otherwise we will wait up to .5 seconds in case
	 * the user reads some more.
	 */
	sk->ack_backlog++;
/*
 * It's unclear whether to use sk->mtu or sk->mss here.  They differ only
 * if the other end is offering a window smaller than the agreed on MSS
 * (called sk->mtu here).  In theory there's no connection between send
 * and receive, and so no reason to think that they're going to send
 * small packets.  For the moment I'm using the hack of reducing the mss
 * only on the send side, so I'm putting mtu here.
 */
	if ((sk->prot->rspace(sk) > (sk->window - sk->bytes_rcv + sk->mtu))) {
		/* Send an ack right now. */
		tcp_read_wakeup(sk);
	} else {
		/* Force it to send an ack soon. */
		int was_active = del_timer(&sk->timer);
		if (!was_active || TCP_ACK_TIME < sk->timer.expires) {
			reset_timer(sk, TIME_WRITE, TCP_ACK_TIME);
		} else
			add_timer(&sk->timer);
	}
  }
} 


/* Handle reading urgent data. */
static int
tcp_read_urg(struct sock * sk, int nonblock,
	     unsigned char *to, int len, unsigned flags)
{
	struct wait_queue wait = { current, NULL };

	while (len > 0) {
		if (sk->urginline || !sk->urg_data || sk->urg_data == URG_READ)
			return -EINVAL;
		if (sk->urg_data & URG_VALID) {
			char c = sk->urg_data;
			if (!(flags & MSG_PEEK))
				sk->urg_data = URG_READ;
			put_fs_byte(c, to);
			return 1;
		}

		if (sk->err) {
			int tmp = -sk->err;
			sk->err = 0;
			return tmp;
		}

		if (sk->state == TCP_CLOSE || sk->done) {
			if (!sk->done) {
				sk->done = 1;
				return 0;
			}
			return -ENOTCONN;
		}

		if (sk->shutdown & RCV_SHUTDOWN) {
			sk->done = 1;
			return 0;
		}

		if (nonblock)
			return -EAGAIN;

		if (current->signal & ~current->blocked)
			return -ERESTARTSYS;

		current->state = TASK_INTERRUPTIBLE;
		add_wait_queue(sk->sleep, &wait);
		if ((sk->urg_data & URG_NOTYET) && sk->err == 0 &&
		    !(sk->shutdown & RCV_SHUTDOWN))
			schedule();
		remove_wait_queue(sk->sleep, &wait);
		current->state = TASK_RUNNING;
	}
	return 0;
}


/* This routine copies from a sock struct into the user buffer. */
static int tcp_read(struct sock *sk, unsigned char *to,
	int len, int nonblock, unsigned flags)
{
	struct wait_queue wait = { current, NULL };
	int copied = 0;
	unsigned long peek_seq;
	unsigned long *seq;
	unsigned long used;
	int err;

	if (len == 0)
		return 0;

	if (len < 0)
		return -EINVAL;

	err = verify_area(VERIFY_WRITE, to, len);
	if (err)
		return err;

	/* This error should be checked. */
	if (sk->state == TCP_LISTEN)
		return -ENOTCONN;

	/* Urgent data needs to be handled specially. */
	if (flags & MSG_OOB)
		return tcp_read_urg(sk, nonblock, to, len, flags);

	peek_seq = sk->copied_seq;
	seq = &sk->copied_seq;
	if (flags & MSG_PEEK)
		seq = &peek_seq;

	add_wait_queue(sk->sleep, &wait);
	sk->inuse = 1;
	while (len > 0) {
		struct sk_buff * skb;
		unsigned long offset;
	
		/*
		 * are we at urgent data? Stop if we have read anything.
		 */
		if (copied && sk->urg_data && sk->urg_seq == 1+*seq)
			break;

		current->state = TASK_INTERRUPTIBLE;

		skb = sk->rqueue;
		do {
			if (!skb)
				break;
			if (before(1+*seq, skb->h.th->seq))
				break;
			offset = 1 + *seq - skb->h.th->seq;
			if (skb->h.th->syn)
				offset--;
			if (offset < skb->len)
				goto found_ok_skb;
			if (!(flags & MSG_PEEK))
				skb->used = 1;
			skb = (struct sk_buff *)skb->next;
		} while (skb != sk->rqueue);

		if (copied)
			break;

		if (sk->err) {
			copied = -sk->err;
			sk->err = 0;
			break;
		}

		if (sk->state == TCP_CLOSE) {
			if (!sk->done) {
				sk->done = 1;
				break;
			}
			copied = -ENOTCONN;
			break;
		}

		if (sk->shutdown & RCV_SHUTDOWN) {
			sk->done = 1;
			break;
		}
			
		if (nonblock) {
			copied = -EAGAIN;
			break;
		}

		cleanup_rbuf(sk);
		release_sock(sk);
		schedule();
		sk->inuse = 1;

		if (current->signal & ~current->blocked) {
			copied = -ERESTARTSYS;
			break;
		}
		continue;

	found_ok_skb:
		/* Ok so how much can we use ? */
		used = skb->len - offset;
		if (len < used)
			used = len;
		/* do we have urgent data here? */
		if (sk->urg_data) {
			unsigned long urg_offset = sk->urg_seq - (1 + *seq);
			if (urg_offset < used) {
				if (!urg_offset) {
					if (!sk->urginline) {
						++*seq;
						offset++;
						used--;
					}
				} else
					used = urg_offset;
			}
		}
		/* Copy it */
		memcpy_tofs(to,((unsigned char *)skb->h.th) +
			skb->h.th->doff*4 + offset, used);
		copied += used;
		len -= used;
		to += used;
		*seq += used;
		if (after(sk->copied_seq+1,sk->urg_seq))
			sk->urg_data = 0;
		if (!(flags & MSG_PEEK) && (used + offset >= skb->len))
			skb->used = 1;
	}
	remove_wait_queue(sk->sleep, &wait);
	current->state = TASK_RUNNING;

	/* Clean up data we have read: This will do ACK frames */
	cleanup_rbuf(sk);
	release_sock(sk);
	DPRINTF((DBG_TCP, "tcp_read: returning %d\n", copied));
	return copied;
}

 
/*
 * Send a FIN without closing the connection.
 * Not called at interrupt time.
 */
void
tcp_shutdown(struct sock *sk, int how)
{
  struct sk_buff *buff;
  struct tcphdr *t1, *th;
  struct proto *prot;
  int tmp;
  struct device *dev = NULL;

  /*

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成熟亚洲日本毛茸茸凸凹| 欧美一级片在线看| 欧美视频三区在线播放| 亚洲精品一区二区三区99| 国产精品久久免费看| 丝瓜av网站精品一区二区 | 国产精品18久久久久| 91丨九色丨尤物| 久久精品一区二区三区不卡 | 欧美无砖砖区免费| 国产午夜精品美女毛片视频| 亚洲成人动漫在线免费观看| 成人午夜看片网址| 久久这里只有精品首页| 日韩精品一区第一页| 99久久99久久精品免费观看| 精品国产乱码久久久久久1区2区 | 欧美网站一区二区| 欧美国产亚洲另类动漫| 久久精品国产999大香线蕉| 欧美最猛黑人xxxxx猛交| 国产精品每日更新在线播放网址| 麻豆国产欧美一区二区三区| 欧美久久久久久蜜桃| 亚洲图片欧美色图| 欧美亚洲动漫精品| 亚洲精品视频一区| 一本到高清视频免费精品| 国产精品美女一区二区三区| 国产99久久久精品| 国产亚洲成aⅴ人片在线观看 | 久久综合色婷婷| 日本欧美一区二区三区乱码| 欧美日本一区二区在线观看| 亚洲福利视频一区| 91精品中文字幕一区二区三区 | ...av二区三区久久精品| 成人视屏免费看| 国产精品系列在线| av一本久道久久综合久久鬼色| 国产午夜精品美女毛片视频| 成人免费毛片aaaaa**| 中国色在线观看另类| 99久久精品费精品国产一区二区| 亚洲素人一区二区| 欧洲精品在线观看| 午夜欧美在线一二页| 91麻豆精品国产无毒不卡在线观看| 日韩电影免费在线观看网站| 日韩精品中文字幕在线一区| 国产精品99久久久久久久女警 | 日韩欧美高清在线| 国产在线播放一区二区三区| 久久精品人人爽人人爽| 成人av电影在线观看| 一区二区三区中文字幕在线观看| 欧美日韩国产综合视频在线观看| 久久爱另类一区二区小说| 国产欧美一区二区三区在线看蜜臀 | 国产精品福利影院| 欧美体内she精视频| 日韩福利视频网| 国产日韩精品一区二区三区| 色悠久久久久综合欧美99| 石原莉奈在线亚洲二区| 久久久噜噜噜久久中文字幕色伊伊| 波多野洁衣一区| 亚洲国产aⅴ成人精品无吗| 欧美一级在线免费| 99国内精品久久| 日韩黄色免费电影| 国产精品美女久久久久久2018 | 91麻豆精东视频| 日韩中文字幕一区二区三区| 久久久久久99精品| 在线视频你懂得一区| 国产一区二区导航在线播放| 国产精品久久久99| 日韩一级成人av| 色妹子一区二区| 国产一区二区不卡| 五月综合激情婷婷六月色窝| 久久精品免费在线观看| 欧美日韩mp4| a在线播放不卡| 九色porny丨国产精品| 亚洲一区二区三区不卡国产欧美| 精品国产乱码久久久久久闺蜜| 欧美影院午夜播放| 波多野结衣中文字幕一区| 精品一区二区三区香蕉蜜桃 | 综合色天天鬼久久鬼色| 精品国产髙清在线看国产毛片| 在线观看视频一区二区欧美日韩| 成人免费三级在线| 蜜桃一区二区三区在线观看| 亚洲国产日韩一级| 亚洲三级久久久| 国产精品色婷婷| 欧美大片一区二区三区| 在线播放/欧美激情| 91福利视频网站| av一区二区三区在线| 粉嫩aⅴ一区二区三区四区| 激情六月婷婷综合| 精品一区二区在线观看| 午夜一区二区三区在线观看| 亚洲黄一区二区三区| 国产精品久久久久久久裸模| 亚洲第一主播视频| 一区二区三区欧美日韩| 亚洲精品欧美激情| 亚洲欧美日韩国产成人精品影院| 久久综合久久综合亚洲| 欧美成人精精品一区二区频| 日韩欧美高清dvd碟片| 日韩一区二区三区av| 日韩一区二区中文字幕| 欧美精品粉嫩高潮一区二区| 色伊人久久综合中文字幕| 99久精品国产| 色美美综合视频| 欧美亚洲另类激情小说| 欧美三级视频在线播放| 欧美日韩一卡二卡| 日韩一区二区免费在线观看| 51午夜精品国产| 日韩三级高清在线| 26uuu亚洲综合色| 亚洲人妖av一区二区| 国产精品毛片久久久久久久| 亚洲色图欧美在线| 亚洲第一综合色| 日精品一区二区三区| 精一区二区三区| 成人国产在线观看| 日本精品视频一区二区| 欧美美女一区二区三区| 日韩视频不卡中文| 久久久久99精品国产片| 日韩毛片精品高清免费| 亚瑟在线精品视频| 日本v片在线高清不卡在线观看| 九九**精品视频免费播放| 成人黄色国产精品网站大全在线免费观看 | 亚洲精品一区二区三区香蕉| 国产亚洲自拍一区| 最新久久zyz资源站| 亚洲在线观看免费| 久久电影网电视剧免费观看| 成人午夜伦理影院| 欧美日韩精品一区二区天天拍小说| 91精品午夜视频| 国产精品福利一区| 日本不卡123| 99热这里都是精品| 欧美日韩卡一卡二| 亚洲国产精品成人久久综合一区| 一区二区三区国产| 国产在线麻豆精品观看| 在线观看亚洲精品视频| 久久久精品国产免费观看同学| 亚洲日本青草视频在线怡红院| 美女一区二区久久| 成人免费看视频| 精品国产一区二区国模嫣然| 亚洲精品乱码久久久久久久久| 久久激情五月婷婷| 色呦呦网站一区| 日本一二三四高清不卡| 日韩国产一二三区| 日本二三区不卡| 国产精品无遮挡| 激情欧美一区二区三区在线观看| 欧美色网站导航| 国产午夜精品一区二区三区视频 | 国产一区二区剧情av在线| 欧美四级电影网| 国产精品激情偷乱一区二区∴| 美洲天堂一区二卡三卡四卡视频| 在线视频国内自拍亚洲视频| 中文字幕免费在线观看视频一区| 人妖欧美一区二区| 91福利国产精品| 国产精品久久毛片av大全日韩| 极品少妇xxxx偷拍精品少妇| 日韩一级大片在线观看| 丝袜美腿高跟呻吟高潮一区| 精品视频一区二区三区免费| 一个色综合网站| 99在线视频精品| 国产精品嫩草影院av蜜臀| 国产精品 日产精品 欧美精品| 欧美不卡在线视频| 欧美aaaaaa午夜精品| 在线成人高清不卡| 亚洲444eee在线观看| 欧美日韩一区二区在线视频| 亚洲一区国产视频| 在线免费观看一区|