⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp_send.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		{			tcp_conn->tc_rtt= tcp_conn->tc_rtt/2+1;assert (tcp_conn->tc_rtt);		}		if (seg_ack == tcp_conn->tc_SND_NXT)			tcp_conn->tc_ett= 0;		else		{			tcp_conn->tc_ett += (seg_ack-tcp_conn->				tc_SND_UNA) * tcp_conn->tc_rtt /				(tcp_conn->tc_SND_NXT-tcp_conn->				tc_SND_UNA);		}		queue_lo= tcp_conn->tc_SND_UNA;		queue_hi= tcp_conn->tc_SND_NXT;		tcp_conn->tc_SND_UNA= seg_ack;		if (tcp_Lmod4G(tcp_conn->tc_SND_TRM, seg_ack))			tcp_conn->tc_SND_TRM= seg_ack;		if (tcp_Lmod4G(tcp_conn->tc_snd_cwnd, seg_ack))		{			tcp_conn->tc_snd_cwnd= seg_ack;#if DEBUG & 256 { where(); printf("snd_cwnd is now %d\n", tcp_conn->tc_snd_cwnd); }#endif		}		if (queue_lo == tcp_conn->tc_ISS)			queue_lo++;		if (tcp_conn->tc_flags & TCF_FIN_SENT)		{			if (seg_ack == queue_hi)				seg_ack--;			if (queue_lo == queue_hi)				queue_lo--;			queue_hi--;		}		offset= seg_ack - queue_lo;		size= queue_hi - seg_ack;		old_pack= tcp_conn->tc_send_data;		tcp_conn->tc_send_data= 0;		if (!size)		{			new_pack= 0;			tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + 				2*tcp_conn->tc_mss;			/* Reset window if a write is completed */#if DEBUG & 256 { where(); printf("snd_cwnd is now %d\n", tcp_conn->tc_snd_cwnd); }#endif		}		else			new_pack= bf_cut(old_pack, offset, size);		bf_afree(old_pack);		tcp_conn->tc_send_data= new_pack;assert (tcp_check_conn(tcp_conn));		if (tcp_conn->tc_state == TCS_CLOSED)		{	 { where(); printf("connection closed while inuse\n"); }			return;		}		if (tcp_conn->tc_ett)		{#if DEBUG & 256 { where(); printf("setting major_to\n"); }#endif			clck_timer(&tcp_conn->tc_major_timer,			tcp_conn->tc_ett + tcp_conn->tc_rtt,			major_to, tcp_conn-tcp_conn_table);		}	}	mss= tcp_conn->tc_mss;	cthresh= tcp_conn->tc_snd_cthresh;	mss2= 2*mss;	if (new_win < mss2)	{		cwnd= 0;		if (new_win >= mss)			incr= mss;		else		{			if (new_win)				incr= new_win;			else				incr= 1;		}	}	else	{		cwnd= tcp_conn->tc_snd_cwnd - tcp_conn->tc_SND_UNA;		incr= mss2;		if (cwnd+incr > new_win)		{			incr= mss;			if (cwnd+incr > new_win)				incr= 0;		}	}assert (cthresh >= mss2);	if (incr && cwnd+incr >  cthresh)	{		incr -= mss;		if (incr && cwnd+incr >  cthresh)			incr -= mss;	}	if (cwnd+incr+mss>cthresh && cthresh<tcp_conn->tc_snd_wnd)		tcp_conn->tc_snd_cthresh += tcp_conn->tc_snd_cinc;	tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA+cwnd+incr;#if DEBUG & 256 { where(); printf("snd_cwnd is now 0x%x\n", tcp_conn->tc_snd_cwnd); }#endif	if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd))		tcp_conn->tc_SND_TRM= tcp_conn->tc_snd_cwnd;	if (tcp_Gmod4G(tcp_conn->tc_snd_cwnd, tcp_conn->tc_SND_TRM) &&		tcp_Gmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_TRM))		tcp_restart_write(tcp_conn);	if (tcp_conn->tc_writeuser)		tcp_restart_fd_write(tcp_conn);assert (tcp_check_conn(tcp_conn));}PUBLIC void tcp_restart_fd_write(tcp_conn)tcp_conn_t *tcp_conn;{	tcp_fd_t *urgent_fd, *normal_fd, *shutdown_fd,		*new_fd, *hi_fd, *tcp_fd;	int closed_connection;#if DEBUG & 256 { where(); printf("in restart_fd_write\n"); }#endif	do	{		tcp_fd= tcp_conn->tc_writeuser;		closed_connection= (tcp_conn->tc_state == TCS_CLOSED);		if (tcp_fd)			fd_write(tcp_fd);		else			tcp_fd= &tcp_fd_table[TCP_FD_NR-1];		if (!closed_connection &&			tcp_conn->tc_state == TCS_CLOSED)		{#if DEBUG  { where(); printf("connection closed while inuse\n"); }#endif			return;		}		if (!tcp_conn->tc_writeuser)		{			urgent_fd= 0;			normal_fd= 0;			shutdown_fd= 0;			for (new_fd= tcp_fd+1, hi_fd=				&tcp_fd_table[TCP_FD_NR]; new_fd<hi_fd;				new_fd++)				switch_write_fd(tcp_conn, new_fd,					&urgent_fd, &normal_fd,					&shutdown_fd);			for (new_fd= tcp_fd_table, hi_fd= tcp_fd+1;				new_fd < hi_fd; new_fd++)				switch_write_fd(tcp_conn, new_fd,					&urgent_fd, &normal_fd,					&shutdown_fd);			if (urgent_fd)				tcp_fd= urgent_fd;			else if (normal_fd)				tcp_fd= normal_fd;			else				tcp_fd= shutdown_fd;			tcp_conn->tc_writeuser= tcp_fd;		}		else			return;	} while (tcp_conn->tc_writeuser);}PRIVATE void switch_write_fd (tcp_conn, new_fd, ref_urg_fd,	ref_norm_fd, ref_shut_fd)tcp_conn_t *tcp_conn;tcp_fd_t *new_fd, **ref_urg_fd, **ref_norm_fd, **ref_shut_fd;{	if (!(new_fd->tf_flags & TFF_INUSE))		return;	if (new_fd->tf_conn != tcp_conn)		return;	if (new_fd->tf_flags & TFF_WRITE_IP)		if (new_fd->tf_flags & TFF_WR_URG)		{			if (!*ref_urg_fd)				*ref_urg_fd= new_fd;		}		else		{			if (!*ref_norm_fd)				*ref_norm_fd= new_fd;		}	else if ((new_fd->tf_flags & TFF_IOCTL_IP) &&		new_fd->tf_ioreq == NWIOTCPSHUTDOWN)		if (!*ref_shut_fd)			*ref_shut_fd= new_fd;}PRIVATE void fd_write (tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	int urg, push;	u32_t max_seq;	size_t max_count, max_trans, write_count, send_count;	acc_t *data, *tmp_acc, *send_data;	int restart_write;	restart_write= FALSE;	tcp_conn= tcp_fd->tf_conn;	if (tcp_fd->tf_flags & TFF_IOCTL_IP)	{assert (tcp_fd->tf_ioreq == NWIOTCPSHUTDOWN);		if (tcp_conn->tc_state == TCS_CLOSED)		{			tcp_conn->tc_writeuser= 0;			tcp_reply_ioctl (tcp_fd, tcp_conn->tc_error);			return;		}		tcp_conn->tc_writeuser= 0;		tcp_reply_ioctl (tcp_fd, NW_OK);		tcp_shutdown (tcp_conn);		return;	}	assert (tcp_fd->tf_flags & TFF_WRITE_IP);	if (tcp_conn->tc_state == TCS_CLOSED)	{		tcp_conn->tc_writeuser= 0;#if DEBUG & 256 { where(); printf("calling tcp_reply_write()\n"); }#endif		if (tcp_fd->tf_write_offset)			tcp_reply_write(tcp_fd,				tcp_fd->tf_write_offset);		else			tcp_reply_write(tcp_fd, tcp_conn->tc_error);		return;	}assert (!(tcp_conn->tc_flags & TCF_FIN_SENT));assert (tcp_conn->tc_SND_UNA != tcp_conn->tc_ISS);	urg= (tcp_fd->tf_flags & TFF_WR_URG);	push= (tcp_fd->tf_flags & TFF_PUSH_DATA);#if DEBUG & 256 if (push) { where(); printf("pushing data\n"); }#endif	max_seq= tcp_conn->tc_SND_UNA + tcp_conn->tc_snd_wnd;	if (urg)		max_seq += tcp_conn->tc_urg_wnd;	max_count= max_seq - tcp_conn->tc_SND_UNA;	max_trans= max_seq - tcp_conn->tc_SND_NXT;	if (tcp_fd->tf_write_count <= max_trans)		write_count= tcp_fd->tf_write_count;	else if (!urg && max_trans < max_count/2)		return;	else		write_count= max_trans;	if (write_count)	{		data= (*tcp_fd->tf_get_userdata)			(tcp_fd->tf_srfd, tcp_fd->tf_write_offset,			write_count, FALSE);		if (tcp_conn->tc_state == TCS_CLOSED)		{ { where(); printf("connection closed while inuse\n"); }			if (data)				bf_afree(data);			return;		}		if (!data)		{			tcp_conn->tc_writeuser= 0;assert(data);#if DEBUG { where(); printf("calling tcp_reply_write()\n"); }#endif			if (tcp_fd->tf_write_offset)				tcp_reply_write(tcp_fd,					tcp_fd->tf_write_offset);			else				tcp_reply_write(tcp_fd, EFAULT);			return;		}		tcp_fd->tf_write_offset += write_count;		tcp_fd->tf_write_count -= write_count;		send_data= tcp_conn->tc_send_data;		tcp_conn->tc_send_data= 0;		send_data= bf_append(send_data, data);		if (tcp_conn->tc_state == TCS_CLOSED)		{ { where(); printf("connection closed while inuse\n"); }			bf_afree(send_data);			return;		}		tcp_conn->tc_send_data= send_data;		tcp_conn->tc_SND_NXT += write_count;		if (urg)			tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT;		if (push && !tcp_fd->tf_write_count)			tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT;assert (tcp_check_conn(tcp_conn));		if (tcp_Gmod4G(tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_TRM) &&			tcp_Lmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd))			restart_write= TRUE;	}	if (!tcp_fd->tf_write_count)	{		tcp_conn->tc_writeuser= 0;#if DEBUG & 256 { where(); printf("calling tcp_reply_write()\n"); }#endif		tcp_reply_write(tcp_fd, tcp_fd->tf_write_offset);	}	if (restart_write)		tcp_restart_write(tcp_conn);}PUBLIC void tcp_shutdown(tcp_conn)tcp_conn_t *tcp_conn;{	int closed_connection;#if DEBUG & 256 { where(); printf("in tcp_shutdown\n"); }#endif	if (tcp_conn->tc_flags & TCF_FIN_SENT)		return;	tcp_conn->tc_flags |= TCF_FIN_SENT;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif	tcp_conn->tc_SND_NXT++;	switch (tcp_conn->tc_state)	{	case TCS_CLOSED:	case TCS_LISTEN:	case TCS_SYN_SENT:	case TCS_SYN_RECEIVED:#if DEBUG & 256 { where(); printf("calling tcp_close_connection\n"); }#endif		tcp_close_connection(tcp_conn, ENOTCONN);		break;	case TCS_ESTABLISHED:		tcp_conn->tc_state= TCS_FIN_WAIT_1;#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif		break;	case TCS_CLOSE_WAIT:		tcp_conn->tc_state= TCS_LAST_ACK;#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif		break;	}	closed_connection= (tcp_conn->tc_state == TCS_CLOSED);assert (tcp_check_conn(tcp_conn));#if DEBUG & 256 { where(); printf("calling tcp_restart_write\n"); }#endif		tcp_restart_write(tcp_conn);}PUBLIC void tcp_set_time_wait_timer(tcp_conn)tcp_conn_t *tcp_conn;{	assert (tcp_conn->tc_state == TCS_TIME_WAIT);#if DEBUG & 256 { where(); printf("tcp_set_time_wait_timer, ttl= %d\n", tcp_conn->tc_ttl); }#endif	clck_timer(&tcp_conn->tc_time_wait_timer, get_time() +		tcp_conn->tc_ttl * 2L * HZ, time_wait_to, tcp_conn-		tcp_conn_table);}PUBLIC void tcp_set_ack_timer (tcp_conn)tcp_conn_t *tcp_conn;{	if (tcp_conn->tc_flags & TCF_ACK_TIMER_SET)		return;	tcp_conn->tc_flags |= TCF_ACK_TIMER_SET;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif#if DEBUG & 256 { where(); printf("setting ack_timer\n"); };#endif	clck_timer(&tcp_conn->tc_ack_timer, get_time() +		TCP_ACK_DELAY, ack_to, tcp_conn-tcp_conn_table);}/*tcp_close_connection*/PUBLIC void tcp_close_connection(tcp_conn, error)tcp_conn_t *tcp_conn;int error;{#if DEBUG & 256 { where(); printf("closing connection\n"); }#endifassert (tcp_check_conn(tcp_conn));assert (tcp_conn->tc_flags & TCF_INUSE);	tcp_conn->tc_error= error;	if (tcp_conn->tc_state == TCS_CLOSED)		return;	clck_untimer (&tcp_conn->tc_major_timer);	clck_untimer (&tcp_conn->tc_minor_timer);#if DEBUG & 256 { where(); printf("clearing ack_timer\n"); }#endif	clck_untimer (&tcp_conn->tc_ack_timer);	clck_untimer (&tcp_conn->tc_time_wait_timer);	tcp_conn->tc_state= TCS_CLOSED;#if DEBUG & 16 { where(); tcp_write_state(tcp_conn); }#endif	if (tcp_conn->tc_readuser)		tcp_restart_fd_read (tcp_conn);assert (!tcp_conn->tc_readuser);	if (tcp_conn->tc_writeuser)		tcp_restart_fd_write (tcp_conn);assert (!tcp_conn->tc_writeuser);	if (tcp_conn->tc_connuser)	{#if DEBUG & 256 { where(); printf("closing and connuser present\n"); }#endif		tcp_restart_connect (tcp_conn->tc_connuser);	}assert (!tcp_conn->tc_connuser);	if (tcp_conn->tc_rcvd_data)	{		bf_afree(tcp_conn->tc_rcvd_data);		tcp_conn->tc_rcvd_data= 0;	}	tcp_conn->tc_flags &= ~TCF_FIN_RECV;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif	tcp_conn->tc_RCV_LO= tcp_conn->tc_RCV_NXT;	if (tcp_conn->tc_rcv_queue)	{		bf_afree(tcp_conn->tc_rcv_queue);		tcp_conn->tc_rcv_queue= 0;	}	if (tcp_conn->tc_send_data)	{#if DEBUG & 256 { where(); printf("releasing data\n"); }#endif#if DEBUG & 256 { where(); printf("SND_TRM= 0x%lx, tc_SND_NXT= 0x%lx, SND_UNA=  0x%lx\n",	tcp_conn->tc_SND_TRM, tcp_conn->tc_SND_NXT, tcp_conn->tc_SND_UNA); }#endif		bf_afree(tcp_conn->tc_send_data);		tcp_conn->tc_send_data= 0;		tcp_conn->tc_SND_TRM=			tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA;	}	tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA;	if (tcp_conn->tc_remipopt)	{		bf_afree(tcp_conn->tc_remipopt);		tcp_conn->tc_remipopt= 0;	}	if (tcp_conn->tc_remtcpopt)	{		bf_afree(tcp_conn->tc_remtcpopt);		tcp_conn->tc_remtcpopt= 0;	}	if (tcp_conn->tc_frag2send)	{		bf_afree(tcp_conn->tc_frag2send);		tcp_conn->tc_remtcpopt= 0;	}					/* clear all flags but TCF_INUSE */	tcp_conn->tc_flags &= TCF_INUSE;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endifassert (tcp_check_conn(tcp_conn));}PRIVATE void ack_to(conn, timer)int conn;struct timer *timer;{	tcp_conn_t *tcp_conn;#if DEBUG & 256 { where(); printf("in ack_to\n"); }#endif	tcp_conn= &tcp_conn_table[conn];	assert (&tcp_conn->tc_ack_timer == timer);	assert (tcp_conn->tc_flags & TCF_ACK_TIMER_SET);	tcp_conn->tc_flags &= ~TCF_ACK_TIMER_SET;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif	tcp_conn->tc_flags |= TCF_SEND_ACK;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif	tcp_restart_write (tcp_conn);}PRIVATE void time_wait_to(conn, timer)int conn;struct timer *timer;{	tcp_conn_t *tcp_conn;	tcp_conn= &tcp_conn_table[conn];	assert (tcp_conn->tc_state == TCS_TIME_WAIT);	assert (&tcp_conn->tc_time_wait_timer == timer);#if DEBUG { where(); printf("calling tcp_close_connection\n"); }#endif	tcp_close_connection (tcp_conn, ENOCONN);}PUBLIC void tcp_zero_wnd_to(conn, timer)int conn;struct timer *timer;{	tcp_conn_t *tcp_conn;#if DEBUG & 256 { where(); printf("in tcp_zero_wnd_to\n"); }#endif	tcp_conn= &tcp_conn_table[conn];	assert (&tcp_conn->tc_major_timer == timer);	assert (tcp_conn->tc_0wnd_to);	tcp_conn->tc_0wnd_to *= 2;	tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA;	tcp_restart_write (tcp_conn);}#if DEBUGPRIVATE void tcp_delay_to(ref, timer)int ref;timer_t *timer;{	tcp_port_t *tcp_port;assert(ref >= 0 && ref < TCP_PORT_NR);	tcp_port= &tcp_port_table[ref];assert(timer == &tcp_port->tp_delay_tim);	tcp_port->tp_flags &= ~(TPF_WRITE_SP|TPF_WRITE_IP);	tcp_port->tp_flags |= TPF_DELAY_TCP;	if (tcp_port->tp_flags & TPF_MORE2WRITE)	{#if DEBUG & 256{ where(); printf("calling tcp_restart_write_port\n"); }#endif		write2port(tcp_port, tcp_port->tp_pack);	}}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -