summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_asconf.c
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2009-11-17 13:11:23 +0000
committertuexen <tuexen@FreeBSD.org>2009-11-17 13:11:23 +0000
commitca50a585fce88097cae9f5c40c6222d40b0f3a18 (patch)
tree6d5eff54ac440aa5984dcee10bc8065542f34d88 /sys/netinet/sctp_asconf.c
parentb4f7d47afa49deeb7727a9dee766b8a1344818e4 (diff)
downloadFreeBSD-src-ca50a585fce88097cae9f5c40c6222d40b0f3a18.zip
FreeBSD-src-ca50a585fce88097cae9f5c40c6222d40b0f3a18.tar.gz
Do not start the iterator when there are no associations.
This fixes a bug found by Irene Ruengeler. Approved by: rrs (mentor) MFC after: 1 month
Diffstat (limited to 'sys/netinet/sctp_asconf.c')
-rw-r--r--sys/netinet/sctp_asconf.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 404b5ad..9c46e79 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -3180,24 +3180,6 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
ifa = NULL;
}
if (ifa != NULL) {
- /* add this address */
- struct sctp_asconf_iterator *asc;
- struct sctp_laddr *wi;
-
- SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
- sizeof(struct sctp_asconf_iterator),
- SCTP_M_ASC_IT);
- if (asc == NULL) {
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
- return (ENOMEM);
- }
- wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr),
- struct sctp_laddr);
- if (wi == NULL) {
- SCTP_FREE(asc, SCTP_M_ASC_IT);
- SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
- return (ENOMEM);
- }
if (type == SCTP_ADD_IP_ADDRESS) {
sctp_add_local_addr_ep(inp, ifa, type);
} else if (type == SCTP_DEL_IP_ADDRESS) {
@@ -3205,8 +3187,6 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
if (inp->laddr_count < 2) {
/* can't delete the last local address */
- SCTP_FREE(asc, SCTP_M_ASC_IT);
- SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
return (EINVAL);
}
@@ -3218,27 +3198,49 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
}
}
}
- LIST_INIT(&asc->list_of_work);
- asc->cnt = 1;
- SCTP_INCR_LADDR_COUNT();
- wi->ifa = ifa;
- wi->action = type;
- atomic_add_int(&ifa->refcount, 1);
- LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
- (void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
- sctp_asconf_iterator_stcb,
- sctp_asconf_iterator_ep_end,
- SCTP_PCB_ANY_FLAGS,
- SCTP_PCB_ANY_FEATURES,
- SCTP_ASOC_ANY_STATE,
- (void *)asc, 0,
- sctp_asconf_iterator_end, inp, 0);
+ if (!LIST_EMPTY(&inp->sctp_asoc_list)) {
+ /*
+ * There is no need to start the iterator if the inp
+ * has no associations.
+ */
+ struct sctp_asconf_iterator *asc;
+ struct sctp_laddr *wi;
+
+ SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
+ sizeof(struct sctp_asconf_iterator),
+ SCTP_M_ASC_IT);
+ if (asc == NULL) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
+ return (ENOMEM);
+ }
+ wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
+ if (wi == NULL) {
+ SCTP_FREE(asc, SCTP_M_ASC_IT);
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
+ return (ENOMEM);
+ }
+ LIST_INIT(&asc->list_of_work);
+ asc->cnt = 1;
+ SCTP_INCR_LADDR_COUNT();
+ wi->ifa = ifa;
+ wi->action = type;
+ atomic_add_int(&ifa->refcount, 1);
+ LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
+ (void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
+ sctp_asconf_iterator_stcb,
+ sctp_asconf_iterator_ep_end,
+ SCTP_PCB_ANY_FLAGS,
+ SCTP_PCB_ANY_FEATURES,
+ SCTP_ASOC_ANY_STATE,
+ (void *)asc, 0,
+ sctp_asconf_iterator_end, inp, 0);
+ }
+ return (0);
} else {
/* invalid address! */
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
return (EADDRNOTAVAIL);
}
- return (0);
}
void
OpenPOWER on IntegriCloud