Merge from Chromium at DEPS revision 273901

This commit was generated by merge_to_master.py.

Change-Id: I134db89f4213aeb80ae690775dd58ee33bf4a76e
diff --git a/netinet/sctp.h b/netinet/sctp.h
index 012acec..b4a1fe9 100755
--- a/netinet/sctp.h
+++ b/netinet/sctp.h
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 264679 2014-04-19 19:21:06Z tuexen $");
 #endif
 
 #ifndef _NETINET_SCTP_H_
@@ -422,6 +422,11 @@
 	struct sctp_chunkhdr ch;/* header from chunk in error */
 } SCTP_PACKED;
 
+struct sctp_error_no_user_data {
+	struct sctp_error_cause cause;	/* code=SCTP_CAUSE_NO_USER_DATA */
+	uint32_t tsn;			/* TSN of the empty data chunk */
+} SCTP_PACKED;
+
 /*
  * Main SCTP chunk types we place these here so natd and f/w's in user land
  * can find them.
diff --git a/netinet/sctp_indata.c b/netinet/sctp_indata.c
index 2801704..125c82f 100755
--- a/netinet/sctp_indata.c
+++ b/netinet/sctp_indata.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 264838 2014-04-23 21:20:55Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -844,7 +844,6 @@
 {
 	struct mbuf *op_err;
 	char msg[SCTP_DIAG_INFO_LEN];
-	
 	uint32_t cum_ackp1, prev_tsn, post_tsn;
 	struct sctp_tmit_chunk *at, *prev, *next;
 
@@ -1018,9 +1017,9 @@
 					 * Huh, need the correct STR here,
 					 * they must be the same.
 					 */
-					SCTP_PRINTF("Prev check - Gak, Evil plot, sid:%d not the same as at:%d\n",
-						    chk->rec.data.stream_number,
-						    prev->rec.data.stream_number);
+					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, sid:%d not the same as at:%d\n",
+					        chk->rec.data.stream_number,
+					        prev->rec.data.stream_number);
 					snprintf(msg, sizeof(msg),
 					         "Expect SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
 					         prev->rec.data.stream_number,
@@ -1033,6 +1032,24 @@
 					*abort_flag = 1;
 					return;
 				}
+				if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) !=
+				    (prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
+					/*
+					 * Huh, need the same ordering here,
+					 * they must be the same.
+					 */
+					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, U-bit not constant\n");
+					snprintf(msg, sizeof(msg),
+					         "Expect U-bit=%d for TSN=%8.8x, got U-bit=%d",
+					         (prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0,
+					         chk->rec.data.TSN_seq,
+					         (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_7;
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
+					*abort_flag = 1;
+					return;
+				}
 				if ((prev->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0 &&
 				    chk->rec.data.stream_seq !=
 				    prev->rec.data.stream_seq) {
@@ -1143,6 +1160,24 @@
 					*abort_flag = 1;
 					return;
 				}
+				if ((chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) !=
+				    (next->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
+					/*
+					 * Huh, need the same ordering here,
+					 * they must be the same.
+					 */
+					SCTPDBG(SCTP_DEBUG_INDATA1, "Next check - Gak, Evil plot, U-bit not constant\n");
+					snprintf(msg, sizeof(msg),
+					         "Expect U-bit=%d for TSN=%8.8x, got U-bit=%d",
+					         (next->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0,
+					         chk->rec.data.TSN_seq,
+					         (chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
+					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_12;
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
+					*abort_flag = 1;
+					return;
+				}
 				if ((next->rec.data.rcv_flags & SCTP_DATA_UNORDERED) == 0 &&
 				    chk->rec.data.stream_seq !=
 				    next->rec.data.stream_seq) {
@@ -1694,6 +1729,9 @@
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_15;
 				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
+				if (last_chunk) {
+					*m = NULL;
+				}
 				return (0);
 			} else {
 				if (sctp_does_tsn_belong_to_reasm(asoc, control->sinfo_tsn)) {
@@ -1710,6 +1748,9 @@
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_16;
 					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
+					if (last_chunk) {
+						*m = NULL;
+					}
 					return (0);
 				}
 			}
@@ -1736,6 +1777,9 @@
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_17;
 					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
+					if (last_chunk) {
+						*m = NULL;
+					}
 					return (0);
 				}
 			}
@@ -1798,6 +1842,9 @@
 			} else {
 				sctp_queue_data_to_stream(stcb, asoc, control, abort_flag);
 				if (*abort_flag) {
+					if (last_chunk) {
+						*m = NULL;
+					}
 					return (0);
 				}
 			}
@@ -1810,7 +1857,9 @@
 			 * the assoc is now gone and chk was put onto the
 			 * reasm queue, which has all been freed.
 			 */
-			*m = NULL;
+			if (last_chunk) {
+				*m = NULL;
+			}
 			return (0);
 		}
 	}
@@ -2339,7 +2388,7 @@
 			continue;
 		}
 		if (ch->ch.chunk_type == SCTP_DATA) {
-			if ((size_t)chk_length < sizeof(struct sctp_data_chunk) + 1) {
+			if ((size_t)chk_length < sizeof(struct sctp_data_chunk)) {
 				/*
 				 * Need to send an abort since we had a
 				 * invalid data chunk.
@@ -2359,6 +2408,23 @@
 				                       vrf_id, port);
 				return (2);
 			}
+			if ((size_t)chk_length == sizeof(struct sctp_data_chunk)) {
+				/*
+				 * Need to send an abort since we had an
+				 * empty data chunk.
+				 */
+				struct mbuf *op_err;
+
+				op_err = sctp_generate_no_user_data_cause(ch->dp.tsn);
+				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_19;
+				sctp_abort_association(inp, stcb, m, iphlen,
+				                       src, dst, sh, op_err,
+#if defined(__FreeBSD__)
+				                       use_mflowid, mflowid,
+#endif
+				                       vrf_id, port);
+				return (2);
+			}
 #ifdef SCTP_AUDITING_ENABLED
 			sctp_audit_log(0xB1, 0);
 #endif
diff --git a/netinet/sctp_os_userspace.h b/netinet/sctp_os_userspace.h
index bf501d0..f863295 100755
--- a/netinet/sctp_os_userspace.h
+++ b/netinet/sctp_os_userspace.h
@@ -224,7 +224,7 @@
 
 #define bzero(buf, len) memset(buf, 0, len)
 #define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
-#define snprintf(data, size, format, name) _snprintf_s(data, size, _TRUNCATE, format, name)
+#define snprintf(data, size, format, ...) _snprintf_s(data, size, _TRUNCATE, format, __VA_ARGS__)
 #define inline __inline
 #define __inline__ __inline
 #define random() rand()
diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c
index 46ca9d7..72f6bc3 100755
--- a/netinet/sctp_output.c
+++ b/netinet/sctp_output.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 264017 2014-04-01 18:38:04Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -7745,7 +7745,8 @@
 	chk->pad_inplace = 0;
 	chk->no_fr_allowed = 0;
 	chk->rec.data.stream_seq = strq->next_sequence_send;
-	if (rcv_flags & SCTP_DATA_LAST_FRAG) {
+	if ((rcv_flags & SCTP_DATA_LAST_FRAG) &&
+	    !(rcv_flags & SCTP_DATA_UNORDERED)) {
 		strq->next_sequence_send++;
 	}
 	chk->rec.data.stream_number = sp->stream;
diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c
index 393069d..fcacdac 100755
--- a/netinet/sctp_pcb.c
+++ b/netinet/sctp_pcb.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 263922 2014-03-29 21:26:45Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 265455 2014-05-06 16:51:07Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -3152,13 +3152,13 @@
 int
 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
 sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
-		struct sctp_ifa *sctp_ifap, struct thread *p)
+                struct sctp_ifa *sctp_ifap, struct thread *p)
 #elif defined(__Windows__)
 sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
-		struct sctp_ifa *sctp_ifap, PKTHREAD p)
+                struct sctp_ifa *sctp_ifap, PKTHREAD p)
 #else
 sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
-		struct sctp_ifa *sctp_ifap, struct proc *p)
+                struct sctp_ifa *sctp_ifap, struct proc *p)
 #endif
 {
 	/* bind a ep to a socket address */
@@ -3177,7 +3177,6 @@
 	uint32_t vrf_id;
 
 	lport = 0;
-	error = 0;
 	bindall = 1;
 	inp = (struct sctp_inpcb *)so->so_pcb;
 #if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
@@ -3224,14 +3223,14 @@
 			sin = (struct sockaddr_in *)addr;
 			lport = sin->sin_port;
 #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
- 			/*
- 			 * For LOOPBACK the prison_local_ip4() call will transmute the ip address
- 			 * to the proper value.
- 			 */
- 			if (p && (error = prison_local_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
- 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
- 				return (error);
-  			}
+			/*
+			 * For LOOPBACK the prison_local_ip4() call will transmute the ip address
+			 * to the proper value.
+			 */
+			if (p && (error = prison_local_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
+				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+				return (error);
+			}
 #endif
 			if (sin->sin_addr.s_addr != INADDR_ANY) {
 				bindall = 0;
@@ -3255,15 +3254,15 @@
 #endif
 			lport = sin6->sin6_port;
 #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
-  			/*
- 			 * For LOOPBACK the prison_local_ip6() call will transmute the ipv6 address
- 			 * to the proper value.
-  			 */
- 			if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
- 			    (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
- 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
- 				return (error);
- 			}
+			/*
+			 * For LOOPBACK the prison_local_ip6() call will transmute the ipv6 address
+			 * to the proper value.
+			 */
+			if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
+			    (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
+				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
+				return (error);
+			}
 #endif
 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 				bindall = 0;
@@ -3331,7 +3330,7 @@
 	SCTP_INP_INFO_WLOCK();
 	SCTP_INP_WLOCK(inp);
 	/* Setup a vrf_id to be the default for the non-bind-all case. */
- 	vrf_id = inp->def_vrf_id;
+	vrf_id = inp->def_vrf_id;
 
 	/* increase our count due to the unlock we do */
 	SCTP_INP_INCR_REF(inp);
@@ -3355,7 +3354,7 @@
 #elif defined(__APPLE__)
 				  suser(p->p_ucred, &p->p_acflag)
 #elif defined(__Userspace__) /* must be true to use raw socket */
-                                  1
+				  1
 #else
 				  suser(p, 0)
 #endif
@@ -3375,15 +3374,6 @@
 			}
 #endif
 		}
-#if !defined(__Panda__) && !defined(__Userspace__)
-		if (p == NULL) {
-			SCTP_INP_DECR_REF(inp);
-			SCTP_INP_WUNLOCK(inp);
-			SCTP_INP_INFO_WUNLOCK();
-			SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
-			return (error);
-		}
-#endif
 #endif /* __Windows__ */
 		SCTP_INP_WUNLOCK(inp);
 		if (bindall) {
@@ -3464,7 +3454,7 @@
 		}
 	} else {
 		uint16_t first, last, candidate;
-                uint16_t count;
+		uint16_t count;
 		int done;
 
 #if defined(__Windows__)
@@ -3472,12 +3462,12 @@
 		last = 0xffff;
 #else
 #if defined(__Userspace__)
-                /* TODO ensure uid is 0, etc... */
+		/* TODO ensure uid is 0, etc... */
 #elif defined(__FreeBSD__) || defined(__APPLE__)
-                if (ip_inp->inp_flags & INP_HIGHPORT) {
-                        first = MODULE_GLOBAL(ipport_hifirstauto);
-                        last  = MODULE_GLOBAL(ipport_hilastauto);
-                } else if (ip_inp->inp_flags & INP_LOWPORT) {
+		if (ip_inp->inp_flags & INP_HIGHPORT) {
+			first = MODULE_GLOBAL(ipport_hifirstauto);
+			last = MODULE_GLOBAL(ipport_hilastauto);
+		} else if (ip_inp->inp_flags & INP_LOWPORT) {
 			if (p && (error =
 #ifdef __FreeBSD__
 #if __FreeBSD_version > 602000
@@ -3499,14 +3489,14 @@
 				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
 				return (error);
 			}
-                        first = MODULE_GLOBAL(ipport_lowfirstauto);
-                        last  = MODULE_GLOBAL(ipport_lowlastauto);
-                } else {
+			first = MODULE_GLOBAL(ipport_lowfirstauto);
+			last = MODULE_GLOBAL(ipport_lowlastauto);
+		} else {
 #endif
  			first = MODULE_GLOBAL(ipport_firstauto);
  			last = MODULE_GLOBAL(ipport_lastauto);
 #if defined(__FreeBSD__) || defined(__APPLE__)
-                }
+		}
 #endif
 #endif /* __Windows__ */
 		if (first > last) {
@@ -3707,7 +3697,7 @@
 		/* Put it into tcp 1-2-1 hash */
 		head = &SCTP_BASE_INFO(sctp_tcpephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashtcpmark))];
 		inp->sctp_flags |= SCTP_PCB_FLAGS_IN_TCPPOOL;
-	}  else {
+	} else {
 		head = &SCTP_BASE_INFO(sctp_ephash)[SCTP_PCBHASH_ALLADDR(lport, SCTP_BASE_INFO(hashmark))];
 	}
 	/* put it in the bucket */
diff --git a/netinet/sctp_sha1.c b/netinet/sctp_sha1.c
index 95e4721..c86517f 100755
--- a/netinet/sctp_sha1.c
+++ b/netinet/sctp_sha1.c
@@ -206,7 +206,6 @@
 			    ptr, number_left);
 			ctx->how_many_in_block += number_left;
 			ctx->running_total += number_left;
-			number_left = 0;
 			break;
 		} else {
 			/* block is now full, process it */
diff --git a/netinet/sctputil.c b/netinet/sctputil.c
index 56a2257..38cbcf7 100755
--- a/netinet/sctputil.c
+++ b/netinet/sctputil.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 264701 2014-04-20 18:15:23Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -4253,9 +4253,6 @@
 		case SCTP_INIT:
 			contains_init_chunk = 1;
 			break;
-		case SCTP_COOKIE_ECHO:
-			/* We hit here only if the assoc is being freed */
-			return;
 		case SCTP_PACKET_DROPPED:
 			/* we don't respond to pkt-dropped */
 			return;
@@ -5106,6 +5103,25 @@
 	return (m);
 }
 
+struct mbuf *
+sctp_generate_no_user_data_cause(uint32_t tsn)
+{
+	struct mbuf *m;
+	struct sctp_error_no_user_data *no_user_data_cause;
+	size_t len;
+
+	len = sizeof(struct sctp_error_no_user_data);
+	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
+	if (m != NULL) {
+		SCTP_BUF_LEN(m) = len;
+		no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
+		no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
+		no_user_data_cause->cause.length = htons((uint16_t)len);
+		no_user_data_cause->tsn = tsn; /* tsn is passed in as NBO */
+	}
+	return (m);
+}
+
 #ifdef SCTP_MBCNT_LOGGING
 void
 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
diff --git a/netinet/sctputil.h b/netinet/sctputil.h
index 9815a4c..eec6c80 100755
--- a/netinet/sctputil.h
+++ b/netinet/sctputil.h
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 264679 2014-04-19 19:21:06Z tuexen $");
 #endif
 
 #ifndef _NETINET_SCTP_UTIL_H_
@@ -271,6 +271,7 @@
 );
 
 struct mbuf *sctp_generate_cause(uint16_t, char *);
+struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
 
 void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
 			    struct sockaddr *sa, sctp_assoc_t assoc_id,
diff --git a/user_ip_icmp.h b/user_ip_icmp.h
index 4cd243f..e713417 100755
--- a/user_ip_icmp.h
+++ b/user_ip_icmp.h
@@ -54,6 +54,7 @@
 };
 
 #if defined(__Userspace_os_Windows)
+#pragma pack (push, 1)
 struct icmp6_hdr {
 	u_int8_t icmp6_type;
 	u_int8_t icmp6_code;
@@ -63,7 +64,8 @@
 		u_int16_t icmp6_un_data16[2];
 		u_int8_t icmp6_un_data8[4];
 	} icmp6_dataun;
-} __packed;
+};
+#pragma pack()
 
 #define icmp6_data32 icmp6_dataun.icmp6_un_data32
 #define icmp6_mtu icmp6_data32[0]
diff --git a/user_socket.c b/user_socket.c
index e4e886f..adb798c 100755
--- a/user_socket.c
+++ b/user_socket.c
@@ -2784,7 +2784,6 @@
 	int use_udp_tunneling;
 
 	*result = 0;
-	send_count = 0;
 
 	m = SCTP_HEADER_TO_CHAIN(o_pak);
 	m_orig = m;
@@ -2940,7 +2939,6 @@
 	int use_udp_tunneling;
 
 	*result = 0;
-	send_count = 0;
 
 	m = SCTP_HEADER_TO_CHAIN(o_pak);
 	m_orig = m;