diff options
-rw-r--r-- | sys/netinet/sctp_auth.c | 9 | ||||
-rw-r--r-- | sys/netinet/sctp_constants.h | 1 | ||||
-rw-r--r-- | sys/netinet/sctp_header.h | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_indata.c | 39 | ||||
-rw-r--r-- | sys/netinet/sctp_output.c | 11 | ||||
-rw-r--r-- | sys/netinet/sctp_sysctl.c | 9 | ||||
-rw-r--r-- | sys/netinet/sctp_uio.h | 3 | ||||
-rw-r--r-- | usr.bin/netstat/inet.c | 6 | ||||
-rw-r--r-- | usr.bin/netstat/sctp.c | 98 |
9 files changed, 58 insertions, 120 deletions
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 07dbf8b..1c9d528 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -542,7 +542,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys, } } /* shouldn't reach here */ - return (0); + return (EINVAL); } void @@ -622,8 +622,11 @@ sctp_copy_skeylist(const struct sctp_keyhead *src, struct sctp_keyhead *dest) LIST_FOREACH(skey, src, next) { new_skey = sctp_copy_sharedkey(skey); if (new_skey != NULL) { - (void)sctp_insert_sharedkey(dest, new_skey); - count++; + if (sctp_insert_sharedkey(dest, new_skey)) { + sctp_free_sharedkey(new_skey); + } else { + count++; + } } } return (count); diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index a58c206..ecde4fe 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -345,6 +345,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_RTT_FROM_NON_DATA 0 #define SCTP_RTT_FROM_DATA 1 +#define PR_SCTP_UNORDERED_FLAG 0x0001 /* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */ #define SCTP_FIRST_MBUF_RESV 68 diff --git a/sys/netinet/sctp_header.h b/sys/netinet/sctp_header.h index 850290d..3f4948d 100644 --- a/sys/netinet/sctp_header.h +++ b/sys/netinet/sctp_header.h @@ -397,7 +397,7 @@ struct sctp_strseq { struct sctp_strseq_mid { uint16_t stream; - uint16_t reserved; + uint16_t flags; uint32_t msg_id; }; diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 7a2f42c..357a047 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -753,7 +753,7 @@ sctp_handle_old_data(struct sctp_tcb *stcb, struct sctp_association *asoc, struc */ struct sctp_tmit_chunk *chk, *lchk, *tchk; uint32_t fsn; - struct sctp_queued_to_read *nc = NULL; + struct sctp_queued_to_read *nc; int cnt_added; if (control->first_frag_seen == 0) { @@ -768,6 +768,11 @@ restart: TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, lchk) { if (chk->rec.data.fsn_num == fsn) { /* Ok lets add it */ + sctp_alloc_a_readq(stcb, nc); + if (nc == NULL) { + break; + } + memset(nc, 0, sizeof(struct sctp_queued_to_read)); TAILQ_REMOVE(&control->reasm, chk, sctp_next); sctp_add_chk_to_control(control, strm, stcb, asoc, chk); fsn++; @@ -781,7 +786,6 @@ restart: * on the control queue to a new * control. */ - sctp_alloc_a_readq(stcb, nc); sctp_build_readq_entry_from_ctl(nc, control); tchk = TAILQ_FIRST(&control->reasm); if (tchk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { @@ -819,6 +823,7 @@ restart: if (control->on_strm_q) { TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); control->on_strm_q = 0; + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); } if (control->on_read_q == 0) { sctp_add_to_readq(stcb->sctp_ep, stcb, control, @@ -826,16 +831,19 @@ restart: SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); } sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); - if ((nc) && (nc->first_frag_seen)) { + if ((nc->first_frag_seen) && !TAILQ_EMPTY(&nc->reasm)) { /* * Switch to the new guy and * continue */ control = nc; - nc = NULL; goto restart; + } else { + sctp_free_a_readq(stcb, nc); } return (1); + } else { + sctp_free_a_readq(stcb, nc); } } else { /* Can't add more */ @@ -961,11 +969,6 @@ place_chunk: * should not happen since the FSN is a TSN and it * should have been dropped earlier. */ - if (chk->data) { - sctp_m_freem(chk->data); - chk->data = NULL; - } - sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED); sctp_abort_in_reasm(stcb, control, chk, abort_flag, SCTP_FROM_SCTP_INDATA + SCTP_LOC_5); @@ -1026,6 +1029,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc, s control, control->on_strm_q); } #endif + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); control->on_strm_q = 0; } @@ -1080,6 +1084,7 @@ done_un: control, control->on_strm_q); } #endif + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); TAILQ_REMOVE(&strm->inqueue, control, next_instrm); control->on_strm_q = 0; } @@ -1125,6 +1130,7 @@ deliver_more: control, control->on_strm_q); } #endif + SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs); TAILQ_REMOVE(&strm->inqueue, control, next_instrm); control->on_strm_q = 0; } @@ -5277,10 +5283,11 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb, } } + static void sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb, struct sctp_association *asoc, - uint16_t stream, uint32_t seq) + uint16_t stream, uint32_t seq, int ordered, int old) { struct sctp_queued_to_read *control; struct sctp_stream_in *strm; @@ -5295,7 +5302,7 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb, * queue. */ strm = &asoc->strmin[stream]; - control = find_reasm_entry(strm, (uint32_t) seq, 0, 0); + control = find_reasm_entry(strm, (uint32_t) seq, ordered, old); if (control == NULL) { /* Not found */ return; @@ -5427,6 +5434,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, unsigned int num_str; uint32_t sequence; uint16_t stream; + uint16_t ordered, flags; int old; struct sctp_strseq *stseq, strseqbuf; struct sctp_strseq_mid *stseq_m, strseqbuf_m; @@ -5452,6 +5460,12 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, } stream = ntohs(stseq_m->stream); sequence = ntohl(stseq_m->msg_id); + flags = ntohs(stseq_m->flags); + if (flags & PR_SCTP_UNORDERED_FLAG) { + ordered = 0; + } else { + ordered = 1; + } } else { stseq = (struct sctp_strseq *)sctp_m_getptr(m, offset, sizeof(struct sctp_strseq), @@ -5462,6 +5476,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, } stream = ntohs(stseq->stream); sequence = (uint32_t) ntohs(stseq->sequence); + ordered = 1; } /* Convert */ @@ -5487,7 +5502,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb, asoc->fragmented_delivery_inprogress = 0; } strm = &asoc->strmin[stream]; - sctp_flush_reassm_for_str_seq(stcb, asoc, stream, sequence); + sctp_flush_reassm_for_str_seq(stcb, asoc, stream, sequence, ordered, old); TAILQ_FOREACH(ctl, &stcb->sctp_ep->read_queue, next) { if ((ctl->sinfo_stream == stream) && (ctl->sinfo_ssn == sequence)) { diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index d8c3cae..1ad3d0c 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -10383,7 +10383,7 @@ sctp_fill_in_rest: /* no more to look at */ break; } - if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) { + if ((at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) && old) { /* We don't report these */ continue; } @@ -10504,7 +10504,7 @@ sctp_fill_in_rest: tp1 = TAILQ_NEXT(at, sctp_next); if (tp1 == NULL) break; - if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) { + if (old && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) { /* We don't report these */ i--; at = tp1; @@ -10519,8 +10519,11 @@ sctp_fill_in_rest: strseq++; } else { strseq_m->stream = ntohs(at->rec.data.stream_number); - strseq_m->reserved = ntohs(0); strseq_m->msg_id = ntohl(at->rec.data.stream_seq); + if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) + strseq_m->flags = ntohs(PR_SCTP_UNORDERED_FLAG); + else + strseq_m->flags = 0; strseq_m++; } at = tp1; @@ -11937,7 +11940,6 @@ sctp_send_deferred_reset_response(struct sctp_tcb *stcb, return; } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); - sctp_add_stream_reset_result(chk, ent->seq, response); /* setup chunk parameters */ chk->sent = SCTP_DATAGRAM_UNSENT; chk->snd_count = 0; @@ -11952,6 +11954,7 @@ sctp_send_deferred_reset_response(struct sctp_tcb *stcb, ch->chunk_length = htons(chk->book_size); atomic_add_int(&chk->whoTo->ref_count, 1); SCTP_BUF_LEN(chk->data) = chk->send_size; + sctp_add_stream_reset_result(chk, ent->seq, response); /* insert the chunk for sending */ TAILQ_INSERT_TAIL(&asoc->control_send_queue, chk, diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index aeb2e10..de21941 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -279,15 +279,6 @@ sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *st if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { if (local_scope == 0) continue; - if (sin6->sin6_scope_id == 0) { - /* - * bad link - * local - * address - */ - if (sa6_recoverscope(sin6) != 0) - continue; - } } if ((site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) continue; diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index c7e441d..e65b7b5 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -259,7 +259,8 @@ struct sctp_snd_all_completes { /* The lower four bits is an enumeration of PR-SCTP policies */ #define SCTP_PR_SCTP_NONE 0x0000/* Reliable transfer */ #define SCTP_PR_SCTP_TTL 0x0001/* Time based PR-SCTP */ -#define SCTP_PR_SCTP_BUF 0x0002/* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_PRIO 0x0002/* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_BUF SCTP_PR_SCTP_PRIO /* For backwards compatibility */ #define SCTP_PR_SCTP_RTX 0x0003/* Number of retransmissions based PR-SCTP */ #define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX #define SCTP_PR_SCTP_ALL 0x000f/* Used for aggregated stats */ diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index 54ab56f..6f912ac 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -418,10 +418,10 @@ protopr(u_long off, const char *name, int af1, int proto) "Tcpcb"); if (Lflag) xo_emit((Aflag && !Wflag) ? - "{T:/%-5.5s} {T:/%-14.14s} {T:/%-18.18s}" : + "{T:/%-5.5s} {T:/%-32.32s} {T:/%-18.18s}" : ((!Wflag || af1 == AF_INET) ? - "{T:/%-5.5s} {T:/%-14.14s} {T:/%-22.22s}" : - "{T:/%-5.5s} {T:/%-14.14s} {T:/%-45.45s}"), + "{T:/%-5.5s} {T:/%-32.32s} {T:/%-22.22s}" : + "{T:/%-5.5s} {T:/%-32.32s} {T:/%-45.45s}"), "Proto", "Listen", "Local Address"); else if (Tflag) xo_emit((Aflag && !Wflag) ? diff --git a/usr.bin/netstat/sctp.c b/usr.bin/netstat/sctp.c index 0ab933a..fd133e3 100644 --- a/usr.bin/netstat/sctp.c +++ b/usr.bin/netstat/sctp.c @@ -104,93 +104,14 @@ struct xraddr_entry { LIST_ENTRY(xraddr_entry) xraddr_entries; }; -/* - * Construct an Internet address representation. - * If numeric_addr has been supplied, give - * numeric value, otherwise try for symbolic name. - */ #ifdef INET -static char * -inetname(struct in_addr *inp) -{ - char *cp; - static char line[MAXHOSTNAMELEN]; - struct hostent *hp; - struct netent *np; - - cp = 0; - if (!numeric_addr && inp->s_addr != INADDR_ANY) { - int net = inet_netof(*inp); - int lna = inet_lnaof(*inp); - - if (lna == INADDR_ANY) { - np = getnetbyaddr(net, AF_INET); - if (np) - cp = np->n_name; - } - if (cp == NULL) { - hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); - if (hp) { - cp = hp->h_name; - trimdomain(cp, strlen(cp)); - } - } - } - if (inp->s_addr == INADDR_ANY) - strcpy(line, "*"); - else if (cp) { - strlcpy(line, cp, sizeof(line)); - } else { - inp->s_addr = ntohl(inp->s_addr); -#define C(x) ((u_int)((x) & 0xff)) - sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), - C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); - inp->s_addr = htonl(inp->s_addr); - } - return (line); -} +char * +inetname(struct in_addr *inp); #endif #ifdef INET6 -static char ntop_buf[INET6_ADDRSTRLEN]; - -static char * -inet6name(struct in6_addr *in6p) -{ - char *cp; - static char line[50]; - struct hostent *hp; - static char domain[MAXHOSTNAMELEN]; - static int first = 1; - - if (first && !numeric_addr) { - first = 0; - if (gethostname(domain, MAXHOSTNAMELEN) == 0 && - (cp = strchr(domain, '.'))) - (void) strcpy(domain, cp + 1); - else - domain[0] = 0; - } - cp = 0; - if (!numeric_addr && !IN6_IS_ADDR_UNSPECIFIED(in6p)) { - hp = gethostbyaddr((char *)in6p, sizeof(*in6p), AF_INET6); - if (hp) { - if ((cp = strchr(hp->h_name, '.')) && - !strcmp(cp + 1, domain)) - *cp = 0; - cp = hp->h_name; - } - } - if (IN6_IS_ADDR_UNSPECIFIED(in6p)) - strcpy(line, "*"); - else if (cp) - strcpy(line, cp); - else - sprintf(line, "%s", - inet_ntop(AF_INET6, (void *)in6p, ntop_buf, - sizeof(ntop_buf))); - return (line); -} +char * +inet6name(struct in6_addr *in6p); #endif static void @@ -447,7 +368,8 @@ sctp_process_inpcb(struct xsctp_inpcb *xinpcb, first = 0; } xladdr = (struct xsctp_laddr *)(buf + *offset); - if (Lflag && !is_listening) { + if ((!aflag && is_listening) || + (Lflag && !is_listening)) { sctp_skip_xinpcb_ifneed(buf, buflen, offset); return; } @@ -513,8 +435,10 @@ retry: xo_open_instance("local-address"); if (xladdr_total == 0) { - xo_emit("{:protocol/%-6.6s/%s} {:type/%-5.5s/%s} ", - pname, tname); + if (!Lflag) { + xo_emit("{:protocol/%-6.6s/%s} " + "{:type/%-5.5s/%s} ", pname, tname); + } } else { xo_emit("\n"); xo_emit(Lflag ? "{P:/%-21.21s} " : "{P:/%-12.12s} ", @@ -529,7 +453,7 @@ retry: "{:state/CLOSED}", " "); } else { xo_emit("{P:/%-45.45s} " - "{:state:LISTEN}", " "); + "{:state/LISTEN}", " "); } } else { if (process_closed) { |