函数tcp_output负责发送报文段,代码中很多地方都调用了它。
tcp_usrreq在多种请求处理中调用了这一函数:处理PRU_CONNECT,发送初始SYN;处理PRU_SHUTDOWN,发送FIN;
处理PRU_RCVD,应用进程从插口接收缓存中读取若干数据后可能需要发送新的窗口大小通告;处理PRU_SEND,发送
数据;处理PRU_SENDOOB,发送带外数据。
tcp_fasttimo调用它发送延迟的ACK。
tcp_timers在重传定时器超时时,调用发送窗口探测报文段。
tcp_timers在持续定时器超时时,调用它发送窗口探测报文段。
tcp_drop调用它发送RST。
tcp_disconect调用它发送FIN。
tcp_input在需要输出或需要立即发送ACK时调用它。
tcp_input在收到一个纯ACK报文段且本地有数据发送时调用它。
tcp_input在连续收到3个重复的ACK时,调用它发送一个单一报文段。(快速重传算法)
tcp_output首先确定是否有报文段等待发送,除了存在需要发往连接对端的数据外,tcp输出还受到其他许多因素的控制。
例如,对端可能通告接收窗口为0,阻止TCP发送任何数据;Nagle算法阻止TCP发送大量小报文段;慢启动和避免拥塞
算法限制TCP发送的数据量。相反,有些函数置位一些特殊标志,强迫tcp_output发送报文段,如TF_ACKNOW标志置位
意味着必须发送一个ACK。如果tcp_output确定不发送某个报文段,数据将保留在插口的发送缓存中,等待下一次调用
该函数。