-send(tp) /* send data */
- register struct tcb *tp;
-{
- register struct ucb *up;
- register unsigned long last, wind;
- struct mbuf *m;
- int flags = 0, forced, sent;
- struct mbuf *tcp_sndcopy();
- int len;
-
-COUNT(SEND);
- up = tp->t_ucb;
- tp->snd_lst = tp->snd_nxt;
- forced = 0;
- m = NULL;
-
- if (tp->snd_nxt == tp->iss) { /* first data to be sent */
- flags |= TH_SYN;
- tp->snd_lst++;
- }
-
- /* get seq # of last datum in send buffer */
-
- last = tp->snd_off;
- for (m = up->uc_sbuf; m != NULL; m = m->m_next)
- last += m->m_len;
-
- /* no data to send in buffer */
-
- if (tp->snd_nxt > last) {
-
- /* should we send FIN? don't unless haven't already sent one */
-
- if ((tp->tc_flags&TC_SND_FIN) &&
- (tp->seq_fin == tp->iss || tp->snd_nxt <= tp->seq_fin)) {
-
- flags |= TH_FIN;
- tp->seq_fin = tp->snd_lst++;
- }
-
- } else { /* there is data to send */
-
- /* send data only if there is a window defined */
-
- if (tp->tc_flags&TC_SYN_ACKED) {
-
- wind = tp->snd_una + tp->snd_wnd;
-
- /* use window to limit send */
-
- tp->snd_lst = min(last, wind);
-
- /* make sure we don't do ip fragmentation */
-
- if ((len = tp->snd_lst - tp->snd_nxt) > 1024)
- tp->snd_lst -= len - 1024;
-
- /* set persist timer */
-
- if (tp->snd_lst >= wind)
- tp->t_persist = T_PERS;
- }
-
- /* check if window is closed and must force a byte out */
-
- if ((tp->tc_flags&TC_FORCE_ONE) && (tp->snd_lst == wind)) {
- tp->snd_lst = tp->snd_nxt + 1;
- forced = 1;
- }
-
- /* copy data to send from send buffer */
-
- m = tcp_sndcopy(tp, max(tp->iss+1,tp->snd_nxt), tp->snd_lst);
-
- /* see if EOL should be sent */
-
- if (tp->snd_end > tp->iss && tp->snd_end <= tp->snd_lst)
- flags |= TH_EOL;
-
- /* must send FIN and no more data left to send after this */
-
- if ((tp->tc_flags&TC_SND_FIN) && !forced &&
- tp->snd_lst == last &&
- (tp->seq_fin == tp->iss || tp->snd_nxt <= tp->seq_fin)) {