亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
蜜桃av一区二区| 欧美日本国产一区| 欧美日韩不卡在线| 中文字幕欧美激情| 麻豆中文一区二区| 91久久线看在观草草青青| 欧美va亚洲va香蕉在线| 亚洲国产视频一区二区| 成人美女视频在线观看18| 欧美变态tickling挠脚心| 午夜国产精品一区| 欧洲精品一区二区三区在线观看| 久久综合精品国产一区二区三区| 日本欧美在线观看| 欧美午夜精品一区二区蜜桃| 亚洲色图制服诱惑| eeuss鲁片一区二区三区在线看| 久久综合成人精品亚洲另类欧美 | 久久久久久免费| 久久国产精品99久久人人澡| 欧美视频精品在线观看| 尤物av一区二区| 欧洲中文字幕精品| 亚洲精品你懂的| 色噜噜狠狠一区二区三区果冻| 国产精品私房写真福利视频| 国产福利一区二区三区在线视频| 精品国产乱码久久久久久免费| 免费观看在线色综合| 欧美一级在线免费| 久久精品国产久精国产| 精品福利视频一区二区三区| 另类小说视频一区二区| 欧美mv和日韩mv的网站| 国产精品一区一区三区| 国产校园另类小说区| 国产成人免费视频一区| 亚洲欧洲一区二区三区| 色网综合在线观看| 亚洲高清中文字幕| 欧美一区二区三区日韩视频| 麻豆91精品视频| 欧美精品一区二区三区四区| 国产乱子轮精品视频| 国产精品久久久久久户外露出| 成人精品国产一区二区4080| 亚洲欧美日韩在线播放| 欧美日韩高清一区二区| 九一九一国产精品| 国产精品夫妻自拍| 69久久99精品久久久久婷婷| 精品一区二区av| 国产精品久久99| 欧美日韩1区2区| 久久99国内精品| 中文字幕在线不卡| 91精品国产aⅴ一区二区| 狠狠色狠狠色合久久伊人| 国产精品人妖ts系列视频| 91久久免费观看| 狠狠久久亚洲欧美| 亚洲欧美日韩精品久久久久| 欧美一区二区三区视频| 成人av在线观| 日韩影院免费视频| 国产精品天美传媒| 日韩一区二区免费在线观看| 高清在线成人网| 亚洲国产精品久久不卡毛片| 精品欧美一区二区久久| 色婷婷香蕉在线一区二区| 强制捆绑调教一区二区| 亚洲欧美日韩人成在线播放| 欧美电视剧免费全集观看| 91一区二区三区在线观看| 麻豆精品一区二区| 亚洲激情男女视频| 精品国内片67194| 91成人在线免费观看| 国产精品91xxx| 日韩精品福利网| 亚洲精品大片www| 日本一区二区三区四区在线视频| 56国语精品自产拍在线观看| av电影在线观看完整版一区二区| 麻豆传媒一区二区三区| 亚洲最新在线观看| 国产精品久久久一本精品| 日韩欧美一区二区不卡| 欧美曰成人黄网| 成av人片一区二区| 国产剧情av麻豆香蕉精品| 日韩成人午夜电影| 午夜视频在线观看一区二区三区| 国产精品久久福利| 国产精品天天看| 国产色产综合色产在线视频| 日韩欧美一区二区免费| 欧美丰满高潮xxxx喷水动漫| 色欧美日韩亚洲| 99精品国产热久久91蜜凸| 国产乱国产乱300精品| 精品一区二区影视| 久久超级碰视频| 麻豆国产欧美一区二区三区| 午夜电影一区二区| 亚洲午夜免费视频| 五月天精品一区二区三区| 亚洲国产一区视频| 亚洲va国产天堂va久久en| 亚洲第一电影网| 婷婷综合另类小说色区| 五月天丁香久久| 日精品一区二区| 美国精品在线观看| 国内精品免费**视频| 国产在线国偷精品产拍免费yy| 久久97超碰色| 国产成人a级片| av一区二区不卡| 色94色欧美sute亚洲线路一久| av激情成人网| 欧美日韩一区高清| 欧美一区二区三区白人| 日韩美女一区二区三区四区| 精品国产精品网麻豆系列| 久久久亚洲午夜电影| 国产精品二三区| 夜夜嗨av一区二区三区中文字幕 | 亚洲欧美日韩中文字幕一区二区三区| 亚洲色图丝袜美腿| 视频一区中文字幕国产| 韩国在线一区二区| 不卡高清视频专区| 欧美日韩情趣电影| 亚洲精品在线观看视频| 国产精品青草久久| 天堂资源在线中文精品| 久久av资源站| av一区二区三区在线| 精品视频在线免费看| 精品国产91九色蝌蚪| 中文字幕一区三区| 日本欧美韩国一区三区| 国产精品一区二区久激情瑜伽| 91婷婷韩国欧美一区二区| 日韩一区二区中文字幕| 国产精品天干天干在观线| 亚洲成人免费影院| 成人18精品视频| 欧美一区二区三区在线观看 | 欧美成人精品3d动漫h| 国产视频一区在线观看| 亚洲主播在线播放| 国产·精品毛片| 91精品福利在线一区二区三区 | 丝袜美腿亚洲综合| www.欧美日韩| 欧美一区二区国产| 一区二区三区国产| 成人精品一区二区三区四区 | 欧美少妇bbb| 亚洲国产精品t66y| 毛片一区二区三区| 欧美性极品少妇| 国产精品国产三级国产专播品爱网 | 国产亲近乱来精品视频| 丝袜美腿亚洲色图| 色欧美日韩亚洲| 国产精品久久久久影院老司| 另类小说欧美激情| 欧美日韩亚洲综合在线| 亚洲美腿欧美偷拍| 成人午夜视频福利| 欧美国产日本韩| 国内国产精品久久| 日韩欧美国产三级| 亚洲高清一区二区三区| 91传媒视频在线播放| 国产精品成人一区二区艾草| 国产一区二区0| 欧美成人a视频| 蜜桃视频在线观看一区| 欧美日韩国产一二三| 亚洲午夜精品17c| 在线观看三级视频欧美| 亚洲精品日日夜夜| 91久久精品国产91性色tv| 国产精品黄色在线观看| 不卡在线视频中文字幕| 国产精品入口麻豆九色| 丁香啪啪综合成人亚洲小说| 日本一区二区三区视频视频| 国产伦理精品不卡| 中文字幕欧美激情| 99国产一区二区三精品乱码| 国产精品久久久久影视| 99视频一区二区三区| 亚洲图片你懂的| 91成人在线精品|