diff options
author | Randall Stewart <rrs@FreeBSD.org> | 2007-05-29 09:29:03 +0000 |
---|---|---|
committer | Randall Stewart <rrs@FreeBSD.org> | 2007-05-29 09:29:03 +0000 |
commit | 207304d4b7d30849b1ccd66369097b2097d5797f (patch) | |
tree | b0a3898608d9bf9a7a2b4c780e734bf27af057e1 /sys/netinet/sctp_bsd_addr.c | |
parent | 20a990117de27fff03b77503a05ed58d727b988a (diff) | |
download | src-207304d4b7d30849b1ccd66369097b2097d5797f.tar.gz src-207304d4b7d30849b1ccd66369097b2097d5797f.zip |
- Fixes so we won't try to start a timer when we
hold a wq lock for the iterator. Panda uses a
silly recursive lock they hold through the timer.
- Add poor mans wireshark compile option..
- Allocate and start using SCTP_M_XXX for all SCTP_MALLOC() calls.
- sysctl now will get back the refcnt for viewing by onlookers.
Reviewed by: gnn
Notes
Notes:
svn path=/head/; revision=170091
Diffstat (limited to 'sys/netinet/sctp_bsd_addr.c')
-rw-r--r-- | sys/netinet/sctp_bsd_addr.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index 4d6fd60e25ba..d188a1225885 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -49,6 +49,38 @@ __FBSDID("$FreeBSD$"); #include <sys/unistd.h> +/* Declare all of our malloc named types */ + +/* Not to Michael/Peter for mac-os, + * I think mac has this to since I + * do see the M_PCB type, so I + * will also put in the mac file the + * MALLOC_DELCARE. If this does not + * work for mac uncomment the defines for + * the strings that we use in Panda, I put + * them in comments in the mac-os file. + */ +MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor"); +MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array"); +MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array"); +MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address"); +MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator"); +MALLOC_DEFINE(SCTP_M_AUTH_CL, "sctp_atcl", "sctp auth chunklist"); +MALLOC_DEFINE(SCTP_M_AUTH_KY, "sctp_atky", "sctp auth key"); +MALLOC_DEFINE(SCTP_M_AUTH_HL, "sctp_athm", "sctp auth hmac list"); +MALLOC_DEFINE(SCTP_M_AUTH_IF, "sctp_athi", "sctp auth info"); +MALLOC_DEFINE(SCTP_M_STRESET, "sctp_stre", "sctp stream reset"); +MALLOC_DEFINE(SCTP_M_CMSG, "sctp_cmsg", "sctp CMSG buffer"); +MALLOC_DEFINE(SCTP_M_COPYAL, "sctp_cpal", "sctp copy all"); +MALLOC_DEFINE(SCTP_M_VRF, "sctp_vrf", "sctp vrf struct"); +MALLOC_DEFINE(SCTP_M_IFA, "sctp_ifa", "sctp ifa struct"); +MALLOC_DEFINE(SCTP_M_IFN, "sctp_ifn", "sctp ifn struct"); +MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block"); +MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list"); +MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control"); +MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option"); + + #if defined(SCTP_USE_THREAD_BASED_ITERATOR) void sctp_wakeup_iterator(void) @@ -338,3 +370,164 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, #endif return (m); } + + +#ifdef SCTP_PACKET_LOGGING + +int packet_log_start = 0; +int packet_log_end = 0; +int packet_log_old_end = SCTP_PACKET_LOG_SIZE; +int packet_log_wrapped = 0; +uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE]; + + +void +sctp_packet_log(struct mbuf *m, int length) +{ + int *lenat, needed, thisone; + void *copyto; + uint32_t *tick_tock; + int total_len, spare; + + total_len = SCTP_SIZE32((length + (2 * sizeof(int)))); + /* Log a packet to the buffer. */ + if (total_len > SCTP_PACKET_LOG_SIZE) { + /* Can't log this packet I have not a buffer big enough */ + return; + } + if (length < (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) { + printf("Huh, length is %d to small for sctp min:%d\n", + length, + (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))); + return; + } + SCTP_IP_PKTLOG_LOCK(); + if ((SCTP_PACKET_LOG_SIZE - packet_log_end) <= total_len) { + /* + * it won't fit on the end. We must go back to the + * beginning. To do this we go back and cahnge + * packet_log_start. + */ + int orig_end; + + lenat = (int *)packet_log_buffer; + orig_end = packet_log_end; + packet_log_old_end = packet_log_end; + packet_log_end = 0; + if (packet_log_start > packet_log_old_end) { + /* calculate the head room */ + spare = packet_log_start - packet_log_old_end; + } else { + spare = 0; + } + needed = total_len - spare; + packet_log_wrapped = 1; + /* Now update the start */ + while (needed > 0) { + thisone = (*(int *)(&packet_log_buffer[packet_log_start])); + needed -= thisone; + if (thisone == 0) { + int *foo; + + foo = (int *)(&packet_log_buffer[packet_log_start]); + goto insane; + } + /* move to next one */ + packet_log_start += thisone; + } + } else { + lenat = (int *)&packet_log_buffer[packet_log_end]; + if (packet_log_start > packet_log_end) { + if ((packet_log_end + total_len) > packet_log_start) { + /* Now need to update killing some packets */ + needed = total_len - ((packet_log_start - packet_log_end)); + while (needed > 0) { + thisone = (*(int *)(&packet_log_buffer[packet_log_start])); + needed -= thisone; + if (thisone == 0) { + goto insane; + } + /* move to next one */ + packet_log_start += thisone; + if (((packet_log_start + sizeof(struct ip)) > SCTP_PACKET_LOG_SIZE) || + (packet_log_wrapped && (packet_log_start >= packet_log_old_end))) { + packet_log_start = 0; + packet_log_old_end = 0; + packet_log_wrapped = 0; + break; + } + } + } + } + } + if (((packet_log_end + total_len) >= SCTP_PACKET_LOG_SIZE) || + ((void *)((caddr_t)lenat) < (void *)packet_log_buffer) || + ((void *)((caddr_t)lenat + total_len) > (void *)&packet_log_buffer[SCTP_PACKET_LOG_SIZE])) { + /* Madness protection */ +insane: + printf("Went mad, end:%d start:%d len:%d wrapped:%d oe:%d - zapping\n", + packet_log_end, packet_log_start, total_len, packet_log_wrapped, packet_log_old_end); + packet_log_start = packet_log_end = packet_log_old_end = packet_log_wrapped = 0; + lenat = (int *)&packet_log_buffer[0]; + } + *lenat = total_len; + lenat++; + tick_tock = (uint32_t *) lenat; + lenat++; + *tick_tock = sctp_get_tick_count(); + copyto = (void *)lenat; + packet_log_end = (((caddr_t)copyto + length) - (caddr_t)packet_log_buffer); + SCTP_IP_PKTLOG_UNLOCK(); + m_copydata(m, 0, length, (caddr_t)copyto); + +} + + +int +sctp_copy_out_packet_log(uint8_t * target, int length) +{ + /* + * We wind through the packet log starting at start copying up to + * length bytes out. We return the number of bytes copied. + */ + int tocopy, this_copy, copied = 0; + void *at; + + tocopy = length; + if (packet_log_start == packet_log_end) { + /* no data */ + return (0); + } + if (packet_log_wrapped) { + /* + * we have a wrapped buffer, we must copy from start to the + * old end. Then copy from the top of the buffer to the end. + */ + SCTP_IP_PKTLOG_LOCK(); + at = (void *)&packet_log_buffer[packet_log_start]; + this_copy = min(tocopy, (packet_log_old_end - packet_log_start)); + memcpy(target, at, this_copy); + tocopy -= this_copy; + copied += this_copy; + if (tocopy == 0) { + SCTP_IP_PKTLOG_UNLOCK(); + return (copied); + } + this_copy = min(tocopy, packet_log_end); + at = (void *)&packet_log_buffer; + memcpy(&target[copied], at, this_copy); + copied += this_copy; + SCTP_IP_PKTLOG_UNLOCK(); + return (copied); + } else { + /* we have one contiguous buffer */ + SCTP_IP_PKTLOG_LOCK(); + at = (void *)&packet_log_buffer; + this_copy = min(length, packet_log_end); + memcpy(target, at, this_copy); + SCTP_IP_PKTLOG_UNLOCK(); + return (this_copy); + } +} + +#endif |