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

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

?? tcp.c

?? LINUX1.0源代碼,代碼條理清晰
?? 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一区二区三区免费野_久草精品视频
国产福利一区二区三区视频在线| 91极品视觉盛宴| 福利一区二区在线| 成人免费视频网站在线观看| 99久久综合精品| 91久久国产最好的精华液| 色屁屁一区二区| 欧美二区在线观看| 久久蜜桃一区二区| 午夜成人免费视频| 日本不卡在线视频| 国产精品99久久久久久有的能看| 成人亚洲一区二区一| 在线精品亚洲一区二区不卡| 在线综合视频播放| 国产亚洲精久久久久久| 国产精品美女久久久久久| 精品国产欧美一区二区| 日韩午夜三级在线| 久久精品视频在线看| 亚洲视频每日更新| 亚洲成国产人片在线观看| 激情另类小说区图片区视频区| 国产91丝袜在线播放| 在线观看av一区二区| 日韩欧美的一区| 精品盗摄一区二区三区| 国产精品三级视频| 性做久久久久久久久| 美国十次综合导航| 95精品视频在线| 精品少妇一区二区| 亚洲视频在线一区观看| 日本vs亚洲vs韩国一区三区二区| 成人一区二区在线观看| 欧美日韩一级二级| 欧美激情在线看| 日韩精品午夜视频| 成人av小说网| 欧美二区在线观看| 亚洲天堂久久久久久久| 久久er99精品| 欧美视频你懂的| 国产精品午夜春色av| 日韩不卡一区二区三区| 久久99精品国产.久久久久| 日本电影欧美片| 久久综合久久综合久久| 中文字幕在线播放不卡一区| 奇米精品一区二区三区在线观看| 成人免费视频caoporn| 91久久精品一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 日韩影院在线观看| 国产剧情一区二区| 欧美性videosxxxxx| 国产色一区二区| 日韩av不卡一区二区| av成人免费在线| 欧美巨大另类极品videosbest | 国产精品私人影院| 美女一区二区视频| 欧美色区777第一页| 国产精品久久久99| 国产露脸91国语对白| 日韩欧美三级在线| 亚洲成人在线观看视频| 成人精品视频一区二区三区尤物| 欧美军同video69gay| 一区二区在线观看av| 成人黄色小视频在线观看| 26uuu亚洲综合色欧美| 亚洲大片一区二区三区| 日本高清成人免费播放| 国产精品天美传媒沈樵| 国产精品一级黄| 久久这里都是精品| 黄页网站大全一区二区| 欧美精品国产精品| 亚洲成av人片一区二区三区 | 欧美视频一区二| 一区二区三区产品免费精品久久75| 成人精品视频一区二区三区尤物| 久久久噜噜噜久久人人看 | 精品欧美一区二区在线观看 | 91精选在线观看| 亚洲精品成a人| 色综合天天综合色综合av| 中文字幕在线不卡| 成人高清在线视频| 久久精品视频免费| 国产98色在线|日韩| 久久精品亚洲一区二区三区浴池| 蜜臀av性久久久久蜜臀aⅴ| 欧美一级国产精品| 青青国产91久久久久久| 91精品国产综合久久国产大片| 日日夜夜一区二区| 欧美日产国产精品| 五月激情综合网| 3d动漫精品啪啪| 另类小说综合欧美亚洲| 日韩精品影音先锋| 国产一区二区三区| 国产亚洲精品福利| 成人美女视频在线观看18| 国产精品欧美极品| 色婷婷综合视频在线观看| 亚洲一区二区三区激情| 欧美性猛交xxxx黑人交| 中文字幕一区二区三区在线观看 | 久久美女艺术照精彩视频福利播放| 蜜臀精品一区二区三区在线观看 | 中文av一区二区| 91视频在线观看免费| 亚洲国产综合91精品麻豆| 欧美日韩黄色影视| 狠狠色丁香婷婷综合久久片| 2021国产精品久久精品| 美女在线一区二区| 国产情人综合久久777777| 91女人视频在线观看| 婷婷中文字幕一区三区| www激情久久| 色综合咪咪久久| 视频一区二区三区入口| 精品国产乱码91久久久久久网站| 国产又粗又猛又爽又黄91精品| 精品国产凹凸成av人网站| 国产精品18久久久久久vr| 亚洲啪啪综合av一区二区三区| 精品视频在线免费看| 亚洲va天堂va国产va久| 日韩欧美国产高清| 成人av电影观看| 日本在线不卡一区| 精品粉嫩aⅴ一区二区三区四区| 国产精品538一区二区在线| 中文字幕一区二区不卡 | 国产成人av福利| 亚洲精品老司机| 欧美日韩综合在线免费观看| 麻豆免费看一区二区三区| 国产片一区二区| 欧美日本韩国一区二区三区视频| 国内精品写真在线观看| 亚洲成人自拍网| 国产精品免费免费| 欧美一区二区三区免费视频 | 亚洲免费视频中文字幕| 在线成人免费观看| 99热这里都是精品| 久久精品国产亚洲5555| 一区二区三区四区亚洲| 久久精品一区二区三区av| 欧美人牲a欧美精品| proumb性欧美在线观看| 久久疯狂做爰流白浆xx| 亚洲精品欧美激情| 欧美激情综合五月色丁香| 欧美一区二区三区免费视频| 91美女片黄在线| 国产盗摄一区二区| 日本中文在线一区| 中文一区一区三区高中清不卡| 欧美一区二区三区四区视频| 在线一区二区三区| 成人aa视频在线观看| 国产美女精品一区二区三区| 婷婷成人激情在线网| 亚洲另类色综合网站| 亚洲三级小视频| 中文字幕综合网| 亚洲欧美日韩中文播放| 亚洲欧美色综合| 亚洲精品视频在线看| 亚洲精品菠萝久久久久久久| 亚洲另类春色国产| 一区二区三区波多野结衣在线观看| 亚洲欧洲三级电影| 椎名由奈av一区二区三区| 国产精品白丝在线| 亚洲人成网站色在线观看| 亚洲激情自拍视频| 亚洲综合成人网| 午夜婷婷国产麻豆精品| 视频一区在线播放| 日本aⅴ亚洲精品中文乱码| 麻豆视频观看网址久久| 精品午夜久久福利影院 | 日本一区二区综合亚洲| 日本一区二区免费在线| 国产精品天美传媒沈樵| 亚洲天堂中文字幕| 亚洲自拍偷拍图区| 丝袜美腿成人在线| 精品中文字幕一区二区| 国产成人在线网站| 99国内精品久久| 欧美日韩成人高清|