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

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

?? tcp.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 5 頁
字號:
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the  BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		Implementation of the Transmission Control Protocol(TCP).
 *
 * Version:	@(#)tcp.c	1.0.16	05/25/93
 *
 * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Mark Evans, <evansmp@uhura.aston.ac.uk>
 *		Corey Minyard <wf-rch!minyard@relay.EU.net>
 *		Florian La Roche, <flla@stud.uni-sb.de>
 *
 * Fixes:	
 *		Alan Cox	:	Numerous verify_area() calls
 *		Alan Cox	:	Set the ACK bit on a reset
 *		Alan Cox	:	Stopped it crashing if it closed while sk->inuse=1
 *					and was trying to connect (tcp_err()).
 *		Alan Cox	:	All icmp error handling was broken
 *					pointers passed where wrong and the
 *					socket was looked up backwards. Nobody
 *					tested any icmp error code obviously.
 *		Alan Cox	:	tcp_err() now handled properly. It wakes people
 *					on errors. select behaves and the icmp error race
 *					has gone by moving it into sock.c
 *		Alan Cox	:	tcp_reset() fixed to work for everything not just
 *					packets for unknown sockets.
 *		Alan Cox	:	tcp option processing.
 *		Alan Cox	:	Reset tweaked (still not 100%) [Had syn rule wrong]
 *		Herp Rosmanith  :	More reset fixes
 *		Alan Cox	:	No longer acks invalid rst frames. Acking
 *					any kind of RST is right out.
 *		Alan Cox	:	Sets an ignore me flag on an rst receive
 *					otherwise odd bits of prattle escape still
 *		Alan Cox	:	Fixed another acking RST frame bug. Should stop
 *					LAN workplace lockups.
 *		Alan Cox	: 	Some tidyups using the new skb list facilities
 *		Alan Cox	:	sk->keepopen now seems to work
 *		Alan Cox	:	Pulls options out correctly on accepts
 *		Alan Cox	:	Fixed assorted sk->rqueue->next errors
 *		Alan Cox	:	PSH doesn't end a TCP read. Switched a bit to skb ops.
 *		Alan Cox	:	Tidied tcp_data to avoid a potential nasty.
 *		Alan Cox	:	Added some beter commenting, as the tcp is hard to follow
 *		Alan Cox	:	Removed incorrect check for 20 * psh
 *	Michael O'Reilly	:	ack < copied bug fix.
 *	Johannes Stille		:	Misc tcp fixes (not all in yet).
 *		Alan Cox	:	FIN with no memory -> CRASH
 *		Alan Cox	:	Added socket option proto entries. Also added awareness of them to accept.
 *		Alan Cox	:	Added TCP options (SOL_TCP)
 *		Alan Cox	:	Switched wakeup calls to callbacks, so the kernel can layer network sockets.
 *		Alan Cox	:	Use ip_tos/ip_ttl settings.
 *		Alan Cox	:	Handle FIN (more) properly (we hope).
 *		Alan Cox	:	RST frames sent on unsynchronised state ack error/
 *		Alan Cox	:	Put in missing check for SYN bit.
 *		Alan Cox	:	Added tcp_select_window() aka NET2E 
 *					window non shrink trick.
 *		Alan Cox	:	Added a couple of small NET2E timer fixes
 *		Charles Hedrick :	TCP fixes
 *		Toomas Tamm	:	TCP window fixes
 *		Alan Cox	:	Small URG fix to rlogin ^C ack fight
 *		Charles Hedrick	:	Window fix
 *		Linus		:	Rewrote tcp_read() and URG handling
 *					completely
 *
 *
 * To Fix:
 *			Possibly a problem with accept(). BSD accept never fails after
 *		it causes a select. Linux can - given the official select semantics I
 *		feel that _really_ its the BSD network programs that are bust (notably
 *		inetd, which hangs occasionally because of this).
 *			Add VJ Fastrecovery algorithm ?
 *			Protocol closedown badly messed up.
 *			Incompatiblity with spider ports (tcp hangs on that 
 *			socket occasionally).
 *		MSG_PEEK and read on same socket at once can cause crashes.
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or(at your option) any later version.
 */
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/termios.h>
#include <linux/in.h>
#include <linux/fcntl.h>
#include "inet.h"
#include "dev.h"
#include "ip.h"
#include "protocol.h"
#include "icmp.h"
#include "tcp.h"
#include "skbuff.h"
#include "sock.h"
#include "arp.h"
#include <linux/errno.h>
#include <linux/timer.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <linux/mm.h>

#define SEQ_TICK 3
unsigned long seq_offset;
#define SUBNETSARELOCAL

static __inline__ int 
min(unsigned int a, unsigned int b)
{
  if (a < b) return(a);
  return(b);
}


static void __print_th(struct tcphdr *th)
{
	unsigned char *ptr;

	printk("TCP header:\n");
	printk("    source=%d, dest=%d, seq =%ld, ack_seq = %ld\n",
		ntohs(th->source), ntohs(th->dest),
		ntohl(th->seq), ntohl(th->ack_seq));
	printk("    fin=%d, syn=%d, rst=%d, psh=%d, ack=%d, urg=%d res1=%d res2=%d\n",
		th->fin, th->syn, th->rst, th->psh, th->ack,
		th->urg, th->res1, th->res2);
	printk("    window = %d, check = %d urg_ptr = %d\n",
		ntohs(th->window), ntohs(th->check), ntohs(th->urg_ptr));
	printk("    doff = %d\n", th->doff);
	ptr =(unsigned char *)(th + 1);
	printk("    options = %d %d %d %d\n", ptr[0], ptr[1], ptr[2], ptr[3]);
}

static inline void print_th(struct tcphdr *th)
{
	if (inet_debug == DBG_TCP)
		__print_th(th);
}

/* This routine grabs the first thing off of a rcv queue. */
static struct sk_buff *
get_firstr(struct sock *sk)
{
  return skb_dequeue(&sk->rqueue);
}

/*
 *	Difference between two values in tcp ack terms.
 */

static long
diff(unsigned long seq1, unsigned long seq2)
{
  long d;

  d = seq1 - seq2;
  if (d > 0) return(d);

  /* I hope this returns what I want. */
  return(~d+1);
}

/* This routine picks a TCP windows for a socket based on
   the following constraints
   
   1. The window can never be shrunk once it is offered (RFC 793)
   2. We limit memory per socket
   
   For now we use NET2E3's heuristic of offering half the memory
   we have handy. All is not as bad as this seems however because
   of two things. Firstly we will bin packets even within the window
   in order to get the data we are waiting for into the memory limit.
   Secondly we bin common duplicate forms at receive time

   Better heuristics welcome
*/
   
static int tcp_select_window(struct sock *sk)
{
	int new_window = sk->prot->rspace(sk);

/*
 * two things are going on here.  First, we don't ever offer a
 * window less than min(sk->mss, MAX_WINDOW/2).  This is the
 * receiver side of SWS as specified in RFC1122.
 * Second, we always give them at least the window they
 * had before, in order to avoid retracting window.  This
 * is technically allowed, but RFC1122 advises against it and
 * in practice it causes trouble.
 */
	if (new_window < min(sk->mss, MAX_WINDOW/2) ||
	    new_window < sk->window)
	  return(sk->window);
	return(new_window);
}

/* Enter the time wait state. */

static void tcp_time_wait(struct sock *sk)
{
  sk->state = TCP_TIME_WAIT;
  sk->shutdown = SHUTDOWN_MASK;
  if (!sk->dead)
	sk->state_change(sk);
  reset_timer(sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
}

/*
 *	A timer event has trigger a tcp retransmit timeout. The
 *	socket xmit queue is ready and set up to send. Because
 *	the ack receive code keeps the queue straight we do
 *	nothing clever here.
 */

static void
tcp_retransmit(struct sock *sk, int all)
{
  if (all) {
	ip_retransmit(sk, all);
	return;
  }

  sk->ssthresh = sk->cong_window >> 1; /* remember window where we lost */
  /* sk->ssthresh in theory can be zero.  I guess that's OK */
  sk->cong_count = 0;

  sk->cong_window = 1;

  /* Do the actual retransmit. */
  ip_retransmit(sk, all);
}


/*
 * This routine is called by the ICMP module when it gets some
 * sort of error condition.  If err < 0 then the socket should
 * be closed and the error returned to the user.  If err > 0
 * it's just the icmp type << 8 | icmp code.  After adjustment
 * header points to the first 8 bytes of the tcp header.  We need
 * to find the appropriate port.
 */
void
tcp_err(int err, unsigned char *header, unsigned long daddr,
	unsigned long saddr, struct inet_protocol *protocol)
{
  struct tcphdr *th;
  struct sock *sk;
  struct iphdr *iph=(struct iphdr *)header;
  
  header+=4*iph->ihl;
   
  DPRINTF((DBG_TCP, "TCP: tcp_err(%d, hdr=%X, daddr=%X saddr=%X, protocol=%X)\n",
					err, header, daddr, saddr, protocol));

  th =(struct tcphdr *)header;
  sk = get_sock(&tcp_prot, th->source/*dest*/, daddr, th->dest/*source*/, saddr);
  print_th(th);

  if (sk == NULL) return;
  
  if(err<0)
  {
  	sk->err = -err;
  	sk->error_report(sk);
  	return;
  }

  if ((err & 0xff00) == (ICMP_SOURCE_QUENCH << 8)) {
	/*
	 * FIXME:
	 * For now we will just trigger a linear backoff.
	 * The slow start code should cause a real backoff here.
	 */
	if (sk->cong_window > 4) sk->cong_window--;
	return;
  }

  DPRINTF((DBG_TCP, "TCP: icmp_err got error\n"));
  sk->err = icmp_err_convert[err & 0xff].errno;

  /*
   * If we've already connected we will keep trying
   * until we time out, or the user gives up.
   */
  if (icmp_err_convert[err & 0xff].fatal) {
	if (sk->state == TCP_SYN_SENT) {
		sk->state = TCP_CLOSE;
		sk->error_report(sk);		/* Wake people up to see the error (see connect in sock.c) */
	}
  }
  return;
}


/*
 *	Walk down the receive queue counting readable data until we hit the end or we find a gap
 *	in the received data queue (ie a frame missing that needs sending to us)
 */

static int
tcp_readable(struct sock *sk)
{
  unsigned long counted;
  unsigned long amount;
  struct sk_buff *skb;
  int count=0;
  int sum;
  unsigned long flags;

  DPRINTF((DBG_TCP, "tcp_readable(sk=%X)\n", sk));
  if(sk && sk->debug)
  	printk("tcp_readable: %p - ",sk);

  if (sk == NULL || skb_peek(&sk->rqueue) == NULL) 	/* Empty sockets are easy! */
  {
  	if(sk && sk->debug) 
  		printk("empty\n");
  	return(0);
  }
  
  counted = sk->copied_seq+1;	/* Where we are at the moment */
  amount = 0;
  
  save_flags(flags);		/* So nobody adds things at the wrong moment */
  cli();
  skb =(struct sk_buff *)sk->rqueue;

  /* Do until a push or until we are out of data. */
  do {
	count++;
#ifdef OLD	
	/* This is wrong: It breaks Chameleon amongst other stacks */
	if (count > 20) {
		restore_flags(flags);
		DPRINTF((DBG_TCP, "tcp_readable, more than 20 packets without a psh\n"));
		printk("tcp_read: possible read_queue corruption.\n");
		return(amount);
	}
#endif	
	if (before(counted, skb->h.th->seq)) 	/* Found a hole so stops here */
		break;
	sum = skb->len -(counted - skb->h.th->seq);	/* Length - header but start from where we are up to (avoid overlaps) */
	if (skb->h.th->syn)
		sum++;
	if (sum >= 0) {					/* Add it up, move on */
		amount += sum;
		if (skb->h.th->syn) amount--;
		counted += sum;
	}
	if (amount && skb->h.th->psh) break;
	skb =(struct sk_buff *)skb->next;		/* Move along */
  } while(skb != sk->rqueue);
  if (amount && !sk->urginline && sk->urg_data &&
      (sk->urg_seq - sk->copied_seq) <= (counted - sk->copied_seq))
	amount--;		/* don't count urg data */
  restore_flags(flags);
  DPRINTF((DBG_TCP, "tcp readable returning %d bytes\n", amount));
  if(sk->debug)
  	printk("got %lu bytes.\n",amount);
  return(amount);
}


/*
 *	Wait for a TCP event. Note the oddity with SEL_IN and reading. The
 *	listening socket has a receive queue of sockets to accept.
 */

static int
tcp_select(struct sock *sk, int sel_type, select_table *wait)
{
  DPRINTF((DBG_TCP, "tcp_select(sk=%X, sel_type = %d, wait = %X)\n",
	  					sk, sel_type, wait));

  sk->inuse = 1;
  switch(sel_type) {
	case SEL_IN:
		if(sk->debug)
			printk("select in");
		select_wait(sk->sleep, wait);
		if(sk->debug)
			printk("-select out");
		if (skb_peek(&sk->rqueue) != NULL) {
			if (sk->state == TCP_LISTEN || tcp_readable(sk)) {
				release_sock(sk);
				if(sk->debug)
					printk("-select ok data\n");
				return(1);
			}
		}
		if (sk->err != 0)	/* Receiver error */
		{
			release_sock(sk);
			if(sk->debug)
				printk("-select ok error");
			return(1);
		}
		if (sk->shutdown & RCV_SHUTDOWN) {
			release_sock(sk);
			if(sk->debug)
				printk("-select ok down\n");
			return(1);
		} else {
			release_sock(sk);
			if(sk->debug)
				printk("-select fail\n");
			return(0);
		}
	case SEL_OUT:
		select_wait(sk->sleep, wait);
		if (sk->shutdown & SEND_SHUTDOWN) {
			DPRINTF((DBG_TCP,
				"write select on shutdown socket.\n"));

			/* FIXME: should this return an error? */
			release_sock(sk);
			return(0);
		}

		/*
		 * FIXME:
		 * Hack so it will probably be able to write
		 * something if it says it's ok to write.
		 */
		if (sk->prot->wspace(sk) >= sk->mss) {
			release_sock(sk);
			/* This should cause connect to work ok. */
			if (sk->state == TCP_SYN_RECV ||
			    sk->state == TCP_SYN_SENT) return(0);
			return(1);
		}
		DPRINTF((DBG_TCP,
			"tcp_select: sleeping on write sk->wmem_alloc = %d, "
			"sk->packets_out = %d\n"
			"sk->wback = %X, sk->wfront = %X\n"
			"sk->write_seq = %u, sk->window_seq=%u\n", 
				sk->wmem_alloc, sk->packets_out,
				sk->wback, sk->wfront,
				sk->write_seq, sk->window_seq));

		release_sock(sk);
		return(0);
	case SEL_EX:
		select_wait(sk->sleep,wait);
		if (sk->err || sk->urg_data) {
			release_sock(sk);
			return(1);
		}
		release_sock(sk);
		return(0);
  }

  release_sock(sk);
  return(0);
}


int
tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
  int err;
  DPRINTF((DBG_TCP, "tcp_ioctl(sk=%X, cmd = %d, arg=%X)\n", sk, cmd, arg));
  switch(cmd) {
	case DDIOCSDBG:
		return(dbg_ioctl((void *) arg, DBG_TCP));

	case TIOCINQ:
#ifdef FIXME	/* FIXME: */
	case FIONREAD:
#endif
		{
			unsigned long amount;

			if (sk->state == TCP_LISTEN) return(-EINVAL);

			sk->inuse = 1;
			amount = tcp_readable(sk);
			release_sock(sk);
			DPRINTF((DBG_TCP, "returning %d\n", amount));
			err=verify_area(VERIFY_WRITE,(void *)arg,
						   sizeof(unsigned long));

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧洲精品一区二区| 午夜激情一区二区| 国产精品综合二区| 欧美电视剧在线观看完整版| 午夜婷婷国产麻豆精品| 欧美日韩专区在线| 亚洲一级电影视频| 欧美色爱综合网| 亚欧色一区w666天堂| 欧美日韩在线三级| 日韩主播视频在线| 91精品国产综合久久久久久漫画| 午夜精品爽啪视频| 7878成人国产在线观看| 视频一区二区中文字幕| 日韩欧美在线观看一区二区三区| 性感美女久久精品| 欧美一区二区三级| 麻豆久久一区二区| 久久综合色婷婷| 国产91精品露脸国语对白| 国产精品美女久久久久高潮| 91麻豆高清视频| 久久精品免费在线观看| 成人高清av在线| 亚洲色图欧美激情| 欧美老女人第四色| 视频在线在亚洲| 久久亚洲精品小早川怜子| 成人激情黄色小说| 亚洲午夜羞羞片| 精品国产亚洲在线| 99久久精品久久久久久清纯| 亚洲一二三专区| 欧美美女bb生活片| 国产麻豆精品在线| 亚洲黄色小说网站| 欧美电影精品一区二区 | 亚洲女女做受ⅹxx高潮| 91无套直看片红桃| 免费成人你懂的| 中文字幕第一区综合| 精品视频色一区| 午夜精品免费在线| 中文在线一区二区| 欧美在线观看你懂的| 黄色小说综合网站| 亚洲人吸女人奶水| 欧美精品一区二区三区蜜桃| 91美女在线观看| 久久精品国产77777蜜臀| 18成人在线观看| 精品噜噜噜噜久久久久久久久试看| 成人97人人超碰人人99| 日韩av午夜在线观看| 国产精品无人区| 日韩免费电影一区| 97久久超碰精品国产| 美国十次综合导航| 亚洲精品国产一区二区精华液| 日韩精品一区国产麻豆| 欧美视频在线不卡| 国产91在线|亚洲| 麻豆精品久久久| 亚洲午夜成aⅴ人片| 国产精品久久久久影院| 91精品国产全国免费观看| 91浏览器在线视频| 国产精品888| 久久99蜜桃精品| 日韩综合在线视频| 亚洲欧美日韩久久| 中文字幕va一区二区三区| 精品国产一区二区三区不卡| 日本韩国精品一区二区在线观看| 国产剧情av麻豆香蕉精品| 日韩成人一级片| 综合久久综合久久| 亚洲丝袜美腿综合| 久久久久久久久伊人| 亚洲综合在线免费观看| 最新热久久免费视频| 亚洲视频一二区| 亚洲欧美日韩久久精品| 一区二区不卡在线播放| 亚洲一区电影777| 视频一区视频二区在线观看| 视频一区在线视频| 狠狠色伊人亚洲综合成人| 国产精品中文字幕欧美| 国产成人免费视频网站高清观看视频| 国模大尺度一区二区三区| 韩国av一区二区| 国产.欧美.日韩| 91免费在线看| 欧美色图天堂网| 欧美一级黄色片| 久久综合九色综合97婷婷| 国产三区在线成人av| 中文字幕在线观看一区| 亚洲国产日韩精品| 免费高清视频精品| 成人中文字幕合集| 欧美在线一区二区| 日韩欧美中文一区| 中文字幕精品一区二区三区精品| 亚洲精品va在线观看| 日本va欧美va精品| 国产 欧美在线| 日本高清成人免费播放| 欧美成人精品福利| 国产精品灌醉下药二区| 三级一区在线视频先锋| 国产一区在线精品| 欧洲激情一区二区| 久久久综合九色合综国产精品| 亚洲人成精品久久久久| 视频在线观看一区| 成人午夜av电影| 在线成人高清不卡| 国产精品嫩草久久久久| 日韩专区在线视频| 91丝袜国产在线播放| 91精品国产综合久久久久久漫画 | 日韩不卡一区二区三区| 风间由美一区二区av101| 在线免费一区三区| 中文字幕av一区 二区| 午夜不卡av在线| 91免费看`日韩一区二区| 日韩女优毛片在线| 亚洲网友自拍偷拍| 白白色 亚洲乱淫| 日韩欧美成人激情| 香蕉久久夜色精品国产使用方法 | 亚洲色图20p| 国产成人啪午夜精品网站男同| 91老司机福利 在线| 久久久久久久久岛国免费| 亚洲国产乱码最新视频 | 精品一区二区在线观看| 欧美色图免费看| 亚洲色图欧美偷拍| 国产精品亚洲综合一区在线观看| 欧美精品18+| 一区二区三区欧美亚洲| 欧美三级电影一区| 夜夜嗨av一区二区三区四季av| 国产成人精品一区二| 欧美α欧美αv大片| 午夜免费欧美电影| 在线观看一区二区精品视频| 最新国产成人在线观看| 懂色一区二区三区免费观看| 精品国产一区二区三区久久久蜜月| 午夜亚洲福利老司机| 欧美在线观看视频在线| 亚洲免费三区一区二区| 不卡欧美aaaaa| 国产精品欧美一级免费| 国产成人丝袜美腿| 国产亚洲欧美激情| 国产福利一区在线| 久久精品夜夜夜夜久久| 国产剧情在线观看一区二区| 2019国产精品| 国产一区二区三区不卡在线观看| 日韩三级视频在线看| 久久99精品国产麻豆不卡| 日韩三级伦理片妻子的秘密按摩| 日韩成人免费看| 欧美一级专区免费大片| 爽好多水快深点欧美视频| 制服丝袜亚洲网站| 日韩激情一区二区| 91麻豆精品国产综合久久久久久| 天天射综合影视| 日韩一区二区电影在线| 免费在线看成人av| 欧美一级在线免费| 激情欧美一区二区| 国产午夜亚洲精品理论片色戒 | 国产在线精品一区二区不卡了| 久久久精品tv| 91在线精品一区二区| 亚洲高清免费一级二级三级| 51午夜精品国产| 国产精品一区在线| 综合中文字幕亚洲| 欧美男生操女生| 国产自产视频一区二区三区| 欧美国产97人人爽人人喊| 成人短视频下载| 亚洲一级二级在线| 欧美精品一区二区精品网| 成人性生交大片免费看在线播放| 亚洲人成精品久久久久| 欧美久久久久久久久久| 日本不卡不码高清免费观看| 91精品国产欧美日韩|