svn commit: r188067 - in head/sys: netinet netinet6
Randall Stewart
rrs at FreeBSD.org
Tue Feb 3 03:04:04 PST 2009
Author: rrs
Date: Tue Feb 3 11:04:03 2009
New Revision: 188067
URL: http://svn.freebsd.org/changeset/base/188067
Log:
- Cleanup checksum code.
- Prepare for CRC offloading, add MIB counters (RS/MT).
- Bugfix: Disable CRC computation for IPv6 addresses with local scope (MT).
- Bugfix: Handle close() with SO_LINGER correctly when notifications
are generated during the close() call(MT).
- Bugfix: Generate DRY event when sender is dry during subscription.
Only for 1-to-1 style sockets (RS/MT)
- Bugfix: Put vtags for the correct amount of time into time-wait (MT).
- Bugfix: Clear vtag entries correctly on expiration (MT).
- Bugfix: shutdown() indicates ENOTCONN when called for unconnected
1-to-1 style sockets (MT).
- Bugfix: In sctp Auth code (PL).
- Add support for devices that support SCTP csum offload (igb).
- Add missing sctp_associd to mib sysctl xsctp_tcb structure (RS)
Obtained from: With help from Peter Lei and Michael Tuexen
Modified:
head/sys/netinet/sctp_auth.c
head/sys/netinet/sctp_constants.h
head/sys/netinet/sctp_crc32.c
head/sys/netinet/sctp_crc32.h
head/sys/netinet/sctp_input.c
head/sys/netinet/sctp_os_bsd.h
head/sys/netinet/sctp_output.c
head/sys/netinet/sctp_pcb.c
head/sys/netinet/sctp_pcb.h
head/sys/netinet/sctp_sysctl.c
head/sys/netinet/sctp_uio.h
head/sys/netinet/sctp_usrreq.c
head/sys/netinet/sctputil.c
head/sys/netinet/sctputil.h
head/sys/netinet6/sctp6_usrreq.c
Modified: head/sys/netinet/sctp_auth.c
==============================================================================
--- head/sys/netinet/sctp_auth.c Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_auth.c Tue Feb 3 11:04:03 2009 (r188067)
@@ -1645,8 +1645,10 @@ sctp_auth_get_cookie_params(struct sctp_
bcopy(p_random->random_data, new_key->key, random_len);
}
#else
- keylen = sizeof(*p_random) + random_len + sizeof(*chunks) + num_chunks +
- sizeof(*hmacs) + hmacs_len;
+ keylen = sizeof(*p_random) + random_len + sizeof(*hmacs) + hmacs_len;
+ if (chunks != NULL) {
+ keylen += sizeof(*chunks) + num_chunks;
+ }
new_key = sctp_alloc_key(keylen);
if (new_key != NULL) {
/* copy in the RANDOM */
Modified: head/sys/netinet/sctp_constants.h
==============================================================================
--- head/sys/netinet/sctp_constants.h Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_constants.h Tue Feb 3 11:04:03 2009 (r188067)
@@ -37,8 +37,15 @@ __FBSDID("$FreeBSD$");
#define __sctp_constants_h__
/* IANA assigned port number for SCTP over UDP encapsulation */
-#define SCTP_OVER_UDP_TUNNELING_PORT 9899
-
+/* For freebsd we cannot bind the port at
+ * startup. Otherwise what will happen is
+ * we really won't be bound. The user must
+ * put it into the sysctl... or we need
+ * to build a special timer for this to allow
+ * us to wait 1 second or so after the system
+ * comes up.
+ */
+#define SCTP_OVER_UDP_TUNNELING_PORT 0
/* Number of packets to get before sack sent by default */
#define SCTP_DEFAULT_SACK_FREQ 2
@@ -310,10 +317,6 @@ __FBSDID("$FreeBSD$");
#define SCTP_PARTIAL_DELIVERY_SHIFT 1
-/* Minimum number of bytes read by user before we
- * condsider doing a rwnd update
- */
-
/*
* default HMAC for cookies, etc... use one of the AUTH HMAC id's
* SCTP_HMAC is the HMAC_ID to use
@@ -323,21 +326,6 @@ __FBSDID("$FreeBSD$");
#define SCTP_SIGNATURE_SIZE SCTP_AUTH_DIGEST_LEN_SHA1
#define SCTP_SIGNATURE_ALOC_SIZE SCTP_SIGNATURE_SIZE
-/* DEFINE HERE WHAT CRC YOU WANT TO USE */
-#define SCTP_USECRC_RFC2960 1
-/* #define SCTP_USECRC_FLETCHER 1 */
-/* #define SCTP_USECRC_SSHCRC32 1 */
-/* #define SCTP_USECRC_FASTCRC32 1 */
-/* #define SCTP_USECRC_CRC32 1 */
-/* #define SCTP_USECRC_TCP32 1 */
-/* #define SCTP_USECRC_CRC16SMAL 1 */
-/* #define SCTP_USECRC_CRC16 1 */
-/* #define SCTP_USECRC_MODADLER 1 */
-
-#ifndef SCTP_ADLER32_BASE
-#define SCTP_ADLER32_BASE 65521
-#endif
-
/*
* the SCTP protocol signature this includes the version number encoded in
* the last 4 bits of the signature.
@@ -619,43 +607,16 @@ __FBSDID("$FreeBSD$");
-/*
- * Number of ticks before the soxwakeup() event that is delayed is sent AFTER
- * the accept() call
- */
-
-/*
- * Of course we really don't collect stale cookies, being folks of decerning
- * taste. However we do count them, if we get too many before the association
- * comes up.. we give up. Below is the constant that dictates when we give it
- * up...this is a implemenation dependent treatment. In ours we do not ask
- * for a extension of time, but just retry this many times...
- */
-
/* max number of TSN's dup'd that I will hold */
#define SCTP_MAX_DUP_TSNS 20
/*
* Here we define the types used when setting the retry amounts.
*/
-/* constants for type of set */
-
-/* Maximum TSN's we will summarize in a drop report */
-
/* How many drop re-attempts we make on INIT/COOKIE-ECHO */
#define SCTP_RETRY_DROPPED_THRESH 4
/*
- * And the max we will keep a history of in the tcb which MUST be lower than
- * 256.
- */
-
-/*
- * Here we define the default timers and the default number of attemts we
- * make for each respective side (send/init).
- */
-
-/*
* Maxmium number of chunks a single association can have on it. Note that
* this is a squishy number since the count can run over this if the user
* sends a large message down .. the fragmented chunks don't count until
@@ -763,7 +724,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_DEBUG_INDATA1 0x01000000
#define SCTP_DEBUG_INDATA2 0x02000000 /* unused */
#define SCTP_DEBUG_INDATA3 0x04000000 /* unused */
-#define SCTP_DEBUG_INDATA4 0x08000000 /* unused */
+#define SCTP_DEBUG_CRCOFFLOAD 0x08000000 /* unused */
#define SCTP_DEBUG_USRREQ1 0x10000000 /* unused */
#define SCTP_DEBUG_USRREQ2 0x20000000 /* unused */
#define SCTP_DEBUG_PEEL1 0x40000000
@@ -783,7 +744,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_INITIAL_CWND 4380
-#define SCTP_DEFAULT_MTU 1500 /* emegency default MTU */
+#define SCTP_DEFAULT_MTU 1500 /* emergency default MTU */
/* amount peer is obligated to have in rwnd or I will abort */
#define SCTP_MIN_RWND 1500
@@ -996,13 +957,6 @@ __FBSDID("$FreeBSD$");
*/
#define SCTP_STACK_VTAG_HASH_SIZE 32
-
-/*
- * If we use the per-endpoint model than we do not have a hash table of
- * entries but instead have a single head pointer and we must crawl through
- * the entire list.
- */
-
/*
* Number of seconds of time wait for a vtag.
*/
Modified: head/sys/netinet/sctp_crc32.c
==============================================================================
--- head/sys/netinet/sctp_crc32.c Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_crc32.c Tue Feb 3 11:04:03 2009 (r188067)
@@ -34,12 +34,16 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/uio.h>
+#include <netinet/sctp.h>
#include <netinet/sctp_os.h>
#include <netinet/sctp_crc32.h>
+#include <netinet/sctp_pcb.h>
-#ifndef SCTP_USE_ADLER32
-
-
+#if !defined(SCTP_WITH_NO_CSUM)
/**
*
* Routine Description:
@@ -80,12 +84,14 @@ __FBSDID("$FreeBSD$");
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o32[256] =
@@ -134,12 +140,14 @@ uint32_t sctp_crc_tableil8_o32[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o40[256] =
@@ -188,12 +196,14 @@ uint32_t sctp_crc_tableil8_o40[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o48[256] =
@@ -242,12 +252,14 @@ uint32_t sctp_crc_tableil8_o48[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o56[256] =
@@ -296,12 +308,14 @@ uint32_t sctp_crc_tableil8_o56[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o64[256] =
@@ -350,12 +364,14 @@ uint32_t sctp_crc_tableil8_o64[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o72[256] =
@@ -404,12 +420,14 @@ uint32_t sctp_crc_tableil8_o72[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o80[256] =
@@ -458,12 +476,14 @@ uint32_t sctp_crc_tableil8_o80[256] =
* The following CRC lookup table was generated automagically using the
* following model parameters:
*
- * Generator Polynomial = ................. 0x1EDC6F41 Generator Polynomial
- * Length = .......... 32 bits Reflected Bits = ....................... TRUE
- * Table Generation Offset = .............. 32 bits Number of Slices =
- * ..................... 8 slices Slice Lengths = ........................ 8
- * 8 8 8 8 8 8 8 Directory Name = ....................... .\ File Name =
- * ............................ 8x256_tables.c
+ * Generator Polynomial = ................. 0x1EDC6F41
+ * Generator Polynomial Length = .......... 32 bits
+ * Reflected Bits = ....................... TRUE
+ * Table Generation Offset = .............. 32 bits
+ * Number of Slices = ..................... 8 slices
+ * Slice Lengths = ........................ 8 8 8 8 8 8 8 8
+ * Directory Name = ....................... .\
+ * File Name = ............................ 8x256_tables.c
*/
uint32_t sctp_crc_tableil8_o88[256] =
@@ -506,6 +526,7 @@ uint32_t sctp_crc_tableil8_o88[256] =
* end of the CRC lookup table crc_tableil8_o88
*/
+
static uint32_t
sctp_crc32c_sb8_64_bit(uint32_t crc,
unsigned char *p_buf,
@@ -578,7 +599,7 @@ sctp_crc32c_sb8_64_bit(uint32_t crc,
*
* none
*/
-uint32_t
+static uint32_t
update_crc32(uint32_t crc32c,
unsigned char *buffer,
unsigned int length)
@@ -662,7 +683,7 @@ uint32_t sctp_crc_c[256] = {
#define SCTP_CRC32C(c,d) (c=(c>>8)^sctp_crc_c[(c^(d))&0xFF])
-uint32_t
+static uint32_t
old_update_crc32(uint32_t crc32c,
unsigned char *buffer,
unsigned int length)
@@ -676,8 +697,8 @@ old_update_crc32(uint32_t crc32c,
}
-uint32_t
-sctp_csum_finalize(uint32_t crc32c)
+static uint32_t
+sctp_finalize_crc32(uint32_t crc32c)
{
uint32_t result;
@@ -709,4 +730,88 @@ sctp_csum_finalize(uint32_t crc32c)
return (crc32c);
}
+#endif /* !defined(SCTP_WITH_NO_CSUM) */
+
+#if defined(SCTP_WITH_NO_CSUM)
+uint32_t
+sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
+{
+ return (0);
+}
+
+#else
+uint32_t
+sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
+{
+ /*
+ * given a mbuf chain with a packetheader offset by 'offset'
+ * pointing at a sctphdr (with csum set to 0) go through the chain
+ * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
+ * has a side bonus as it will calculate the total length of the
+ * mbuf chain. Note: if offset is greater than the total mbuf
+ * length, checksum=1, pktlen=0 is returned (ie. no real error code)
+ */
+ uint32_t base = 0xffffffff;
+ struct mbuf *at;
+
+ at = m;
+ /* find the correct mbuf and offset into mbuf */
+ while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
+ offset -= SCTP_BUF_LEN(at); /* update remaining offset
+ * left */
+ at = SCTP_BUF_NEXT(at);
+ }
+ while (at != NULL) {
+ if ((SCTP_BUF_LEN(at) - offset) > 0) {
+ if ((SCTP_BUF_LEN(at) - offset) < 4) {
+ /* Use old method if less than 4 bytes */
+ base = old_update_crc32(base,
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
+ } else {
+ base = update_crc32(base,
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
+ }
+ /* we only offset once into the first mbuf */
+ }
+ if (offset) {
+ if (offset < (uint32_t) SCTP_BUF_LEN(at))
+ offset = 0;
+ else
+ offset -= SCTP_BUF_LEN(at);
+ }
+ at = SCTP_BUF_NEXT(at);
+ }
+ base = sctp_finalize_crc32(base);
+ return (base);
+}
+
#endif
+
+void
+sctp_delayed_cksum(struct mbuf *m)
+{
+ struct ip *ip;
+ uint32_t checksum;
+ uint32_t offset;
+
+ ip = mtod(m, struct ip *);
+ offset = ip->ip_hl << 2;
+ checksum = sctp_calculate_cksum(m, offset);
+ SCTP_STAT_DECR(sctps_sendhwcrc);
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ offset += offsetof(struct sctphdr, checksum);
+
+ if (offset + sizeof(uint32_t) > (uint32_t) (m->m_len)) {
+ printf("delayed m_pullup, m->len: %d off: %d p: %d\n",
+ (uint32_t) m->m_len, offset, ip->ip_p);
+ /*
+ * XXX this shouldn't happen, but if it does, the correct
+ * behavior may be to insert the checksum in the appropriate
+ * next mbuf in the chain.
+ */
+ return;
+ }
+ *(uint32_t *) (m->m_data + offset) = checksum;
+}
Modified: head/sys/netinet/sctp_crc32.h
==============================================================================
--- head/sys/netinet/sctp_crc32.h Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_crc32.h Tue Feb 3 11:04:03 2009 (r188067)
@@ -36,16 +36,10 @@ __FBSDID("$FreeBSD$");
#ifndef __crc32c_h__
#define __crc32c_h__
-#ifndef SCTP_USE_ADLER32
-
#if defined(_KERNEL) || defined(__Userspace__)
-uint32_t update_crc32(uint32_t, unsigned char *, unsigned int);
-
-uint32_t old_update_crc32(uint32_t, unsigned char *, unsigned int);
-
-uint32_t sctp_csum_finalize(uint32_t);
-
+uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
+void sctp_delayed_cksum(struct mbuf *);
#endif /* _KERNEL */
-#endif /* !SCTP_USE_ADLER32 */
+
#endif /* __crc32c_h__ */
Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_input.c Tue Feb 3 11:04:03 2009 (r188067)
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_timer.h>
+#include <netinet/sctp_crc32.h>
#include <netinet/udp.h>
@@ -1384,14 +1385,6 @@ sctp_process_cookie_existing(struct mbuf
/* FOOBAR */
return (NULL);
}
- /* pre-reserve some space */
-#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
@@ -2504,15 +2497,6 @@ sctp_handle_cookie_echo(struct mbuf *m,
/* FOOBAR */
return (NULL);
}
- /* pre-reserve some space */
-#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
-
/* Set the len */
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
scm = mtod(op_err, struct sctp_stale_cookie_msg *);
@@ -2598,9 +2582,9 @@ sctp_handle_cookie_echo(struct mbuf *m,
}
}
}
- if (to == NULL)
+ if (to == NULL) {
return (NULL);
-
+ }
cookie_len -= SCTP_SIGNATURE_SIZE;
if (*stcb == NULL) {
/* this is the "normal" case... get a new TCB */
@@ -5594,7 +5578,6 @@ sctp_input_with_port(i_pak, off, port)
int refcount_up = 0;
int length, mlen, offset;
-
if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
SCTP_RELEASE_PKT(i_pak);
return;
@@ -5642,6 +5625,11 @@ sctp_input_with_port(i_pak, off, port)
}
ip = mtod(m, struct ip *);
}
+ /* validate mbuf chain length with IP payload length */
+ if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
+ SCTP_STAT_INCR(sctps_hdrops);
+ goto bad;
+ }
sh = (struct sctphdr *)((caddr_t)ip + iphlen);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(*sh));
SCTPDBG(SCTP_DEBUG_INPUT1,
@@ -5659,15 +5647,26 @@ sctp_input_with_port(i_pak, off, port)
goto bad;
}
/* validate SCTP checksum */
+ SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+ "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
+ m->m_pkthdr.len,
+ if_name(m->m_pkthdr.rcvif),
+ m->m_pkthdr.csum_flags);
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
+ SCTP_STAT_INCR(sctps_recvhwcrc);
+ goto sctp_skip_csum_4;
+ }
check = sh->checksum; /* save incoming checksum */
if ((check == 0) && (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback)) &&
((ip->ip_src.s_addr == ip->ip_dst.s_addr) ||
(SCTP_IS_IT_LOOPBACK(m)))
) {
+ SCTP_STAT_INCR(sctps_recvnocrc);
goto sctp_skip_csum_4;
}
sh->checksum = 0; /* prepare for calc */
- calc_check = sctp_calculate_sum(m, &mlen, iphlen);
+ calc_check = sctp_calculate_cksum(m, iphlen);
+ SCTP_STAT_INCR(sctps_recvswcrc);
if (calc_check != check) {
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
calc_check, check, m, mlen, iphlen);
@@ -5699,11 +5698,6 @@ sctp_skip_csum_4:
SCTP_STAT_INCR(sctps_hdrops);
goto bad;
}
- /* validate mbuf chain length with IP payload length */
- if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
- SCTP_STAT_INCR(sctps_hdrops);
- goto bad;
- }
/*
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
* IP/SCTP/first chunk header...
Modified: head/sys/netinet/sctp_os_bsd.h
==============================================================================
--- head/sys/netinet/sctp_os_bsd.h Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_os_bsd.h Tue Feb 3 11:04:03 2009 (r188067)
@@ -154,11 +154,8 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
#define MOD_IPSEC ipsec
/* then define the macro(s) that hook into the vimage macros */
-#if defined(__FreeBSD__) && __FreeBSD_version >= 800056
#define MODULE_GLOBAL(__MODULE, __SYMBOL) V_ ## __SYMBOL
-#else
-#define MODULE_GLOBAL(__MODULE, __SYMBOL) (__SYMBOL)
-#endif
+
/*
*
*/
Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c Tue Feb 3 11:00:43 2009 (r188066)
+++ head/sys/netinet/sctp_output.c Tue Feb 3 11:04:03 2009 (r188067)
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_indata.h>
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_input.h>
+#include <netinet/sctp_crc32.h>
#include <netinet/udp.h>
#include <machine/in_cksum.h>
@@ -5213,6 +5214,9 @@ sctp_lowlevel_chunk_output(struct sctp_i
int ecn_ok,
struct sctp_tmit_chunk *chk,
int out_of_asoc_ok,
+ uint16_t src_port,
+ uint16_t dest_port,
+ uint32_t v_tag,
uint16_t port,
int so_locked,
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
@@ -5237,7 +5241,6 @@ sctp_lowlevel_chunk_output(struct sctp_i
struct mbuf *newm;
struct sctphdr *sctphdr;
int packet_length;
- uint32_t csum;
int ret;
uint32_t vrf_id;
sctp_route_t *ro = NULL;
@@ -5263,51 +5266,27 @@ sctp_lowlevel_chunk_output(struct sctp_i
if ((auth != NULL) && (stcb != NULL)) {
sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
}
- /* Calculate the csum and fill in the length of the packet */
- sctphdr = mtod(m, struct sctphdr *);
- if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
- (stcb) &&
- (to->sa_family == AF_INET) &&
- (stcb->asoc.loopback_scope)) {
- sctphdr->checksum = 0;
- /*
- * This can probably now be taken out since my audit shows
- * no more bad pktlen's coming in. But we will wait a while
- * yet.
- */
- packet_length = sctp_calculate_len(m);
- } else {
- sctphdr->checksum = 0;
- csum = sctp_calculate_sum(m, &packet_length, 0);
- sctphdr->checksum = csum;
- }
-
if (to->sa_family == AF_INET) {
struct ip *ip = NULL;
sctp_route_t iproute;
uint8_t tos_value;
+ int len;
+ len = sizeof(struct ip) + sizeof(struct sctphdr);
if (port) {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
- } else {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1, MT_DATA);
+ len += sizeof(struct udphdr);
}
+ newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
if (newm == NULL) {
sctp_m_freem(m);
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
return (ENOMEM);
}
- if (port) {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip) + sizeof(struct udphdr));
- SCTP_BUF_LEN(newm) = sizeof(struct ip) + sizeof(struct udphdr);
- packet_length += sizeof(struct ip) + sizeof(struct udphdr);
- } else {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip));
- SCTP_BUF_LEN(newm) = sizeof(struct ip);
- packet_length += sizeof(struct ip);
- }
+ SCTP_ALIGN_TO_END(newm, len);
+ SCTP_BUF_LEN(newm) = len;
SCTP_BUF_NEXT(newm) = m;
m = newm;
+ packet_length = sctp_calculate_len(m);
ip = mtod(m, struct ip *);
ip->ip_v = IPVERSION;
ip->ip_hl = (sizeof(struct ip) >> 2);
@@ -5401,12 +5380,21 @@ sctp_lowlevel_chunk_output(struct sctp_i
}
}
if (port) {
- udp = (struct udphdr *)(ip + 1);
+ udp = (struct udphdr *)((caddr_t)ip + sizeof(struct ip));
udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
udp->uh_dport = port;
udp->uh_ulen = htons(packet_length - sizeof(struct ip));
udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
+ sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+ } else {
+ sctphdr = (struct sctphdr *)((caddr_t)ip + sizeof(struct ip));
}
+
+ sctphdr->src_port = src_port;
+ sctphdr->dest_port = dest_port;
+ sctphdr->v_tag = v_tag;
+ sctphdr->checksum = 0;
+
/*
* If source address selection fails and we find no route
* then the ip_output should fail as well with a
@@ -5517,7 +5505,25 @@ sctp_lowlevel_chunk_output(struct sctp_i
#endif
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
if (port) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
SCTP_ENABLE_UDP_CSUM(o_pak);
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ m->m_pkthdr.csum_flags = CSUM_SCTP;
+ m->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
/* send it out. table id is taken from stcb */
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5591,6 +5597,7 @@ sctp_lowlevel_chunk_output(struct sctp_i
struct sockaddr_in6 lsa6_storage;
int error;
u_short prev_port = 0;
+ int len;
if (net != NULL) {
flowlabel = net->tos_flowlabel;
@@ -5598,27 +5605,21 @@ sctp_lowlevel_chunk_output(struct sctp_i
flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
}
+ len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
if (port) {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr) + sizeof(struct udphdr), 1, M_DONTWAIT, 1, MT_DATA);
- } else {
- newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr), 1, M_DONTWAIT, 1, MT_DATA);
+ len += sizeof(struct udphdr);
}
+ newm = sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA);
if (newm == NULL) {
sctp_m_freem(m);
SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
return (ENOMEM);
}
- if (port) {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
- SCTP_BUF_LEN(newm) = sizeof(struct ip6_hdr) + sizeof(struct udphdr);
- packet_length += sizeof(struct ip6_hdr) + sizeof(struct udphdr);
- } else {
- SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr));
- SCTP_BUF_LEN(newm) = sizeof(struct ip6_hdr);
- packet_length += sizeof(struct ip6_hdr);
- }
+ SCTP_ALIGN_TO_END(newm, len);
+ SCTP_BUF_LEN(newm) = len;
SCTP_BUF_NEXT(newm) = m;
m = newm;
+ packet_length = sctp_calculate_len(m);
ip6h = mtod(m, struct ip6_hdr *);
/*
@@ -5763,12 +5764,21 @@ sctp_lowlevel_chunk_output(struct sctp_i
ip6h->ip6_src = lsa6->sin6_addr;
if (port) {
- udp = (struct udphdr *)(ip6h + 1);
+ udp = (struct udphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
udp->uh_sport = htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port));
udp->uh_dport = port;
udp->uh_ulen = htons(packet_length - sizeof(struct ip6_hdr));
udp->uh_sum = 0;
+ sctphdr = (struct sctphdr *)((caddr_t)udp + sizeof(struct udphdr));
+ } else {
+ sctphdr = (struct sctphdr *)((caddr_t)ip6h + sizeof(struct ip6_hdr));
}
+
+ sctphdr->src_port = src_port;
+ sctphdr->dest_port = dest_port;
+ sctphdr->v_tag = v_tag;
+ sctphdr->checksum = 0;
+
/*
* We set the hop limit now since there is a good chance
* that our ro pointer is now filled
@@ -5805,9 +5815,27 @@ sctp_lowlevel_chunk_output(struct sctp_i
#endif
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
if (port) {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ sctphdr->checksum = sctp_calculate_cksum(m, sizeof(struct ip6_hdr) + sizeof(struct udphdr));
+ SCTP_STAT_INCR(sctps_sendswcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
if ((udp->uh_sum = in6_cksum(o_pak, IPPROTO_UDP, sizeof(struct ip6_hdr), packet_length - sizeof(struct ip6_hdr))) == 0) {
udp->uh_sum = 0xffff;
}
+ } else {
+ if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
+ (stcb) &&
+ (stcb->asoc.loopback_scope))) {
+ m->m_pkthdr.csum_flags = CSUM_SCTP;
+ m->m_pkthdr.csum_data = 0; /* FIXME MT */
+ SCTP_STAT_INCR(sctps_sendhwcrc);
+ } else {
+ SCTP_STAT_INCR(sctps_sendnocrc);
+ }
}
/* send it out. table id is taken from stcb */
#if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@@ -5905,7 +5933,7 @@ sctp_send_initiate(struct sctp_inpcb *in
{
struct mbuf *m, *m_at, *mp_last;
struct sctp_nets *net;
- struct sctp_init_msg *initm;
+ struct sctp_init_chunk *init;
struct sctp_supported_addr_param *sup_addr;
struct sctp_adaptation_layer_indication *ali;
struct sctp_ecn_supported_param *ecn;
@@ -5961,7 +5989,7 @@ sctp_send_initiate(struct sctp_inpcb *in
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - mbuf?\n");
return;
}
- SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
/*
* assume peer supports asconf in order to be able to queue local
* address changes while an INIT is in flight and before the assoc
@@ -5969,28 +5997,24 @@ sctp_send_initiate(struct sctp_inpcb *in
*/
stcb->asoc.peer_supports_asconf = 1;
/* Now lets put the SCTP header in place */
- initm = mtod(m, struct sctp_init_msg *);
- initm->sh.src_port = inp->sctp_lport;
- initm->sh.dest_port = stcb->rport;
- initm->sh.v_tag = 0;
- initm->sh.checksum = 0; /* calculate later */
+ init = mtod(m, struct sctp_init_chunk *);
/* now the chunk header */
- initm->msg.ch.chunk_type = SCTP_INITIATION;
- initm->msg.ch.chunk_flags = 0;
+ init->ch.chunk_type = SCTP_INITIATION;
+ init->ch.chunk_flags = 0;
/* fill in later from mbuf we build */
- initm->msg.ch.chunk_length = 0;
+ init->ch.chunk_length = 0;
/* place in my tag */
- initm->msg.init.initiate_tag = htonl(stcb->asoc.my_vtag);
+ init->init.initiate_tag = htonl(stcb->asoc.my_vtag);
/* set up some of the credits. */
- initm->msg.init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
+ init->init.a_rwnd = htonl(max(SCTP_SB_LIMIT_RCV(inp->sctp_socket),
SCTP_MINIMAL_RWND));
- initm->msg.init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
- initm->msg.init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
- initm->msg.init.initial_tsn = htonl(stcb->asoc.init_seq_number);
+ init->init.num_outbound_streams = htons(stcb->asoc.pre_open_streams);
+ init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
+ init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
/* now the address restriction */
- sup_addr = (struct sctp_supported_addr_param *)((caddr_t)initm +
- sizeof(*initm));
+ sup_addr = (struct sctp_supported_addr_param *)((caddr_t)init +
+ sizeof(*init));
sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
#ifdef INET6
/* we support 2 types: IPv6/IPv4 */
@@ -6004,7 +6028,6 @@ sctp_send_initiate(struct sctp_inpcb *in
sup_addr->addr_type[1] = htons(0); /* this is the padding */
#endif
SCTP_BUF_LEN(m) += sizeof(*sup_addr) + sizeof(uint16_t);
-
/* adaptation layer indication parameter */
ali = (struct sctp_adaptation_layer_indication *)((caddr_t)sup_addr + sizeof(*sup_addr) + sizeof(uint16_t));
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
@@ -6013,6 +6036,16 @@ sctp_send_initiate(struct sctp_inpcb *in
SCTP_BUF_LEN(m) += sizeof(*ali);
ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
+ if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
+ /* Add NAT friendly parameter */
+ struct sctp_paramhdr *ph;
+
+ ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
+ ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
+ ph->param_length = htons(sizeof(struct sctp_paramhdr));
+ SCTP_BUF_LEN(m) += sizeof(struct sctp_paramhdr);
+ ecn = (struct sctp_ecn_supported_param *)((caddr_t)ph + sizeof(*ph));
+ }
/* now any cookie time extensions */
if (stcb->asoc.cookie_preserve_req) {
struct sctp_cookie_perserve_param *cookie_preserve;
@@ -6052,19 +6085,22 @@ sctp_send_initiate(struct sctp_inpcb *in
pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
- if (!SCTP_BASE_SYSCTL(sctp_auth_disable))
+ if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
+ }
/*
* EY if the initiator supports nr_sacks, need to report that to
* responder in INIT chunk
*/
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
+ if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)) {
pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
+ }
p_len = sizeof(*pr_supported) + num_ext;
pr_supported->ph.param_length = htons(p_len);
bzero((caddr_t)pr_supported + p_len, SCTP_SIZE32(p_len) - p_len);
SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
+
/* ECN nonce: And now tell the peer we support ECN nonce */
if (SCTP_BASE_SYSCTL(sctp_ecn_nonce)) {
ecn_nonce = (struct sctp_ecn_nonce_supported_param *)
@@ -6073,15 +6109,6 @@ sctp_send_initiate(struct sctp_inpcb *in
ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce));
SCTP_BUF_LEN(m) += sizeof(*ecn_nonce);
}
- if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
- /* Add NAT friendly parameter */
- struct sctp_paramhdr *ph;
-
- ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
- ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
- ph->param_length = htons(sizeof(struct sctp_paramhdr));
- SCTP_BUF_LEN(m) += sizeof(sizeof(struct sctp_paramhdr));
- }
/* add authentication parameters */
if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
struct sctp_auth_random *randp;
@@ -6160,7 +6187,7 @@ sctp_send_initiate(struct sctp_inpcb *in
mp_last = m_at;
p_len += SCTP_BUF_LEN(m_at);
}
- initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr)));
+ init->ch.chunk_length = htons(p_len);
/*
* We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
* here since the timer will drive a retranmission.
@@ -6185,7 +6212,9 @@ sctp_send_initiate(struct sctp_inpcb *in
SCTPDBG(SCTP_DEBUG_OUTPUT4, "Sending INIT - calls lowlevel_output\n");
ret = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
- m, 0, NULL, 0, 0, 0, NULL, 0, net->port, so_locked, NULL);
+ m, 0, NULL, 0, 0, 0, NULL, 0,
+ inp->sctp_lport, stcb->rport, htonl(0),
+ net->port, so_locked, NULL);
SCTPDBG(SCTP_DEBUG_OUTPUT4, "lowlevel_output - %d\n", ret);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, net);
@@ -6711,7 +6740,7 @@ sctp_send_initiate_ack(struct sctp_inpcb
{
struct sctp_association *asoc;
struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last;
- struct sctp_init_msg *initackm_out;
+ struct sctp_init_ack_chunk *initack;
struct sctp_adaptation_layer_indication *ali;
struct sctp_ecn_supported_param *ecn;
struct sctp_prsctp_supported_param *prsctp;
@@ -6776,7 +6805,7 @@ do_a_abort:
sctp_m_freem(op_err);
return;
}
- SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
/* the time I built cookie */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list