Deleted Added
full compact
tcp_output.c (248373) tcp_output.c (249372)
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95
30 */
31
32#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/netinet/tcp_output.c 248373 2013-03-16 08:58:28Z glebius $");
33__FBSDID("$FreeBSD: head/sys/netinet/tcp_output.c 249372 2013-04-11 18:23:56Z glebius $");
34
35#include "opt_inet.h"
36#include "opt_inet6.h"
37#include "opt_ipsec.h"
38#include "opt_tcpdebug.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>

--- 805 unchanged lines hidden (view full) ---

847 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
848 else
849#endif
850 m = m_gethdr(M_NOWAIT, MT_DATA);
851
852 if (m == NULL) {
853 SOCKBUF_UNLOCK(&so->so_snd);
854 error = ENOBUFS;
34
35#include "opt_inet.h"
36#include "opt_inet6.h"
37#include "opt_ipsec.h"
38#include "opt_tcpdebug.h"
39
40#include <sys/param.h>
41#include <sys/systm.h>

--- 805 unchanged lines hidden (view full) ---

847 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
848 else
849#endif
850 m = m_gethdr(M_NOWAIT, MT_DATA);
851
852 if (m == NULL) {
853 SOCKBUF_UNLOCK(&so->so_snd);
854 error = ENOBUFS;
855 sack_rxmit = 0;
855 goto out;
856 }
857
858 m->m_data += max_linkhdr;
859 m->m_len = hdrlen;
860
861 /*
862 * Start the m_copy functions from the closest mbuf

--- 6 unchanged lines hidden (view full) ---

869 mtod(m, caddr_t) + hdrlen);
870 m->m_len += len;
871 } else {
872 m->m_next = m_copy(mb, moff, (int)len);
873 if (m->m_next == NULL) {
874 SOCKBUF_UNLOCK(&so->so_snd);
875 (void) m_free(m);
876 error = ENOBUFS;
856 goto out;
857 }
858
859 m->m_data += max_linkhdr;
860 m->m_len = hdrlen;
861
862 /*
863 * Start the m_copy functions from the closest mbuf

--- 6 unchanged lines hidden (view full) ---

870 mtod(m, caddr_t) + hdrlen);
871 m->m_len += len;
872 } else {
873 m->m_next = m_copy(mb, moff, (int)len);
874 if (m->m_next == NULL) {
875 SOCKBUF_UNLOCK(&so->so_snd);
876 (void) m_free(m);
877 error = ENOBUFS;
878 sack_rxmit = 0;
877 goto out;
878 }
879 }
880
881 /*
882 * If we're sending everything we've got, set PUSH.
883 * (This will keep happy those implementations which only
884 * give data to the user when a buffer fills or

--- 11 unchanged lines hidden (view full) ---

896 else if (SEQ_GT(tp->snd_up, tp->snd_una))
897 TCPSTAT_INC(tcps_sndurg);
898 else
899 TCPSTAT_INC(tcps_sndwinup);
900
901 m = m_gethdr(M_NOWAIT, MT_DATA);
902 if (m == NULL) {
903 error = ENOBUFS;
879 goto out;
880 }
881 }
882
883 /*
884 * If we're sending everything we've got, set PUSH.
885 * (This will keep happy those implementations which only
886 * give data to the user when a buffer fills or

--- 11 unchanged lines hidden (view full) ---

898 else if (SEQ_GT(tp->snd_up, tp->snd_una))
899 TCPSTAT_INC(tcps_sndurg);
900 else
901 TCPSTAT_INC(tcps_sndwinup);
902
903 m = m_gethdr(M_NOWAIT, MT_DATA);
904 if (m == NULL) {
905 error = ENOBUFS;
906 sack_rxmit = 0;
904 goto out;
905 }
906#ifdef INET6
907 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) &&
908 MHLEN >= hdrlen) {
909 MH_ALIGN(m, hdrlen);
910 } else
911#endif

--- 206 unchanged lines hidden (view full) ---

1118 ("%s: mbuf chain shorter than expected: %ld + %u + %u - %u != %u",
1119 __func__, len, hdrlen, ipoptlen, ipsec_optlen, m_length(m, NULL)));
1120#else
1121 KASSERT(len + hdrlen + ipoptlen == m_length(m, NULL),
1122 ("%s: mbuf chain shorter than expected: %ld + %u + %u != %u",
1123 __func__, len, hdrlen, ipoptlen, m_length(m, NULL)));
1124#endif
1125
907 goto out;
908 }
909#ifdef INET6
910 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) &&
911 MHLEN >= hdrlen) {
912 MH_ALIGN(m, hdrlen);
913 } else
914#endif

--- 206 unchanged lines hidden (view full) ---

1121 ("%s: mbuf chain shorter than expected: %ld + %u + %u - %u != %u",
1122 __func__, len, hdrlen, ipoptlen, ipsec_optlen, m_length(m, NULL)));
1123#else
1124 KASSERT(len + hdrlen + ipoptlen == m_length(m, NULL),
1125 ("%s: mbuf chain shorter than expected: %ld + %u + %u != %u",
1126 __func__, len, hdrlen, ipoptlen, m_length(m, NULL)));
1127#endif
1128
1126 /*
1127 * In transmit state, time the transmission and arrange for
1128 * the retransmit. In persist state, just set snd_max.
1129 */
1130 if ((tp->t_flags & TF_FORCEDATA) == 0 ||
1131 !tcp_timer_active(tp, TT_PERSIST)) {
1132 tcp_seq startseq = tp->snd_nxt;
1133
1134 /*
1135 * Advance snd_nxt over sequence space of this segment.
1136 */
1137 if (flags & (TH_SYN|TH_FIN)) {
1138 if (flags & TH_SYN)
1139 tp->snd_nxt++;
1140 if (flags & TH_FIN) {
1141 tp->snd_nxt++;
1142 tp->t_flags |= TF_SENTFIN;
1143 }
1144 }
1145 if (sack_rxmit)
1146 goto timer;
1147 tp->snd_nxt += len;
1148 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
1149 tp->snd_max = tp->snd_nxt;
1150 /*
1151 * Time this transmission if not a retransmission and
1152 * not currently timing anything.
1153 */
1154 if (tp->t_rtttime == 0) {
1155 tp->t_rtttime = ticks;
1156 tp->t_rtseq = startseq;
1157 TCPSTAT_INC(tcps_segstimed);
1158 }
1159 }
1160
1161 /*
1162 * Set retransmit timer if not currently set,
1163 * and not doing a pure ack or a keep-alive probe.
1164 * Initial value for retransmit timer is smoothed
1165 * round-trip time + 2 * round-trip time variance.
1166 * Initialize shift counter which is used for backoff
1167 * of retransmit time.
1168 */
1169timer:
1170 if (!tcp_timer_active(tp, TT_REXMT) &&
1171 ((sack_rxmit && tp->snd_nxt != tp->snd_max) ||
1172 (tp->snd_nxt != tp->snd_una))) {
1173 if (tcp_timer_active(tp, TT_PERSIST)) {
1174 tcp_timer_activate(tp, TT_PERSIST, 0);
1175 tp->t_rxtshift = 0;
1176 }
1177 tcp_timer_activate(tp, TT_REXMT, tp->t_rxtcur);
1178 }
1179 } else {
1180 /*
1181 * Persist case, update snd_max but since we are in
1182 * persist mode (no window) we do not update snd_nxt.
1183 */
1184 int xlen = len;
1185 if (flags & TH_SYN)
1186 ++xlen;
1187 if (flags & TH_FIN) {
1188 ++xlen;
1189 tp->t_flags |= TF_SENTFIN;
1190 }
1191 if (SEQ_GT(tp->snd_nxt + xlen, tp->snd_max))
1192 tp->snd_max = tp->snd_nxt + len;
1193 }
1194
1195 /* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */
1196 hhook_run_tcp_est_out(tp, th, &to, len, tso);
1197
1198#ifdef TCPDEBUG
1199 /*
1200 * Trace.
1201 */
1202 if (so->so_options & SO_DEBUG) {

--- 74 unchanged lines hidden (view full) ---

1277 ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0,
1278 tp->t_inpcb);
1279
1280 if (error == EMSGSIZE && ro.ro_rt != NULL)
1281 mtu = ro.ro_rt->rt_rmx.rmx_mtu;
1282 RO_RTFREE(&ro);
1283 }
1284#endif /* INET */
1129 /* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */
1130 hhook_run_tcp_est_out(tp, th, &to, len, tso);
1131
1132#ifdef TCPDEBUG
1133 /*
1134 * Trace.
1135 */
1136 if (so->so_options & SO_DEBUG) {

--- 74 unchanged lines hidden (view full) ---

1211 ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0,
1212 tp->t_inpcb);
1213
1214 if (error == EMSGSIZE && ro.ro_rt != NULL)
1215 mtu = ro.ro_rt->rt_rmx.rmx_mtu;
1216 RO_RTFREE(&ro);
1217 }
1218#endif /* INET */
1219
1220out:
1221 /*
1222 * In transmit state, time the transmission and arrange for
1223 * the retransmit. In persist state, just set snd_max.
1224 */
1225 if ((tp->t_flags & TF_FORCEDATA) == 0 ||
1226 !tcp_timer_active(tp, TT_PERSIST)) {
1227 tcp_seq startseq = tp->snd_nxt;
1228
1229 /*
1230 * Advance snd_nxt over sequence space of this segment.
1231 */
1232 if (flags & (TH_SYN|TH_FIN)) {
1233 if (flags & TH_SYN)
1234 tp->snd_nxt++;
1235 if (flags & TH_FIN) {
1236 tp->snd_nxt++;
1237 tp->t_flags |= TF_SENTFIN;
1238 }
1239 }
1240 if (sack_rxmit)
1241 goto timer;
1242 tp->snd_nxt += len;
1243 if (SEQ_GT(tp->snd_nxt, tp->snd_max)) {
1244 tp->snd_max = tp->snd_nxt;
1245 /*
1246 * Time this transmission if not a retransmission and
1247 * not currently timing anything.
1248 */
1249 if (tp->t_rtttime == 0) {
1250 tp->t_rtttime = ticks;
1251 tp->t_rtseq = startseq;
1252 TCPSTAT_INC(tcps_segstimed);
1253 }
1254 }
1255
1256 /*
1257 * Set retransmit timer if not currently set,
1258 * and not doing a pure ack or a keep-alive probe.
1259 * Initial value for retransmit timer is smoothed
1260 * round-trip time + 2 * round-trip time variance.
1261 * Initialize shift counter which is used for backoff
1262 * of retransmit time.
1263 */
1264timer:
1265 if (!tcp_timer_active(tp, TT_REXMT) &&
1266 ((sack_rxmit && tp->snd_nxt != tp->snd_max) ||
1267 (tp->snd_nxt != tp->snd_una))) {
1268 if (tcp_timer_active(tp, TT_PERSIST)) {
1269 tcp_timer_activate(tp, TT_PERSIST, 0);
1270 tp->t_rxtshift = 0;
1271 }
1272 tcp_timer_activate(tp, TT_REXMT, tp->t_rxtcur);
1273 }
1274 } else {
1275 /*
1276 * Persist case, update snd_max but since we are in
1277 * persist mode (no window) we do not update snd_nxt.
1278 */
1279 int xlen = len;
1280 if (flags & TH_SYN)
1281 ++xlen;
1282 if (flags & TH_FIN) {
1283 ++xlen;
1284 tp->t_flags |= TF_SENTFIN;
1285 }
1286 if (SEQ_GT(tp->snd_nxt + xlen, tp->snd_max))
1287 tp->snd_max = tp->snd_nxt + len;
1288 }
1289
1285 if (error) {
1286
1287 /*
1288 * We know that the packet was lost, so back out the
1289 * sequence number advance, if any.
1290 *
1291 * If the error is EPERM the packet got blocked by the
1292 * local firewall. Normally we should terminate the

--- 11 unchanged lines hidden (view full) ---

1304 if (sack_rxmit) {
1305 p->rxmit -= len;
1306 tp->sackhint.sack_bytes_rexmit -= len;
1307 KASSERT(tp->sackhint.sack_bytes_rexmit >= 0,
1308 ("sackhint bytes rtx >= 0"));
1309 } else
1310 tp->snd_nxt -= len;
1311 }
1290 if (error) {
1291
1292 /*
1293 * We know that the packet was lost, so back out the
1294 * sequence number advance, if any.
1295 *
1296 * If the error is EPERM the packet got blocked by the
1297 * local firewall. Normally we should terminate the

--- 11 unchanged lines hidden (view full) ---

1309 if (sack_rxmit) {
1310 p->rxmit -= len;
1311 tp->sackhint.sack_bytes_rexmit -= len;
1312 KASSERT(tp->sackhint.sack_bytes_rexmit >= 0,
1313 ("sackhint bytes rtx >= 0"));
1314 } else
1315 tp->snd_nxt -= len;
1316 }
1312out:
1313 SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */
1314 switch (error) {
1315 case EPERM:
1316 tp->t_softerror = error;
1317 return (error);
1318 case ENOBUFS:
1319 if (!tcp_timer_active(tp, TT_REXMT) &&
1320 !tcp_timer_active(tp, TT_PERSIST))

--- 236 unchanged lines hidden ---
1317 SOCKBUF_UNLOCK_ASSERT(&so->so_snd); /* Check gotos. */
1318 switch (error) {
1319 case EPERM:
1320 tp->t_softerror = error;
1321 return (error);
1322 case ENOBUFS:
1323 if (!tcp_timer_active(tp, TT_REXMT) &&
1324 !tcp_timer_active(tp, TT_PERSIST))

--- 236 unchanged lines hidden ---