MFC r295549:
Loopback addresses are 127.0.0.0/8, not 127.0.0.1/32. MFC r295668: Improve the teardown of the SCTP stack. MFC r295670: Whitespace changes. MFC r295708: Address a warning reported by D5245 / PVS. MFC r295709: Code cleanup which will silence a warning in PVS / D5245. MFC r295710: Add protection code for issues reported by PVS / D5245. MFC r295771: Fix reporting of mapped addressed in getpeername() and getsockname() for IPv6 SCTP sockets. This bugs were found because of an issue reported by PVS / D5245. MFC r295772: Add some protection code. MFC r295773: Add protection code. MFC r295805: Use the SCTP level pointer, not the interface level. MFC r295929: Don't leak an address in an error path. Approved by: re (marius)
This commit is contained in:
parent
5be4dc53c1
commit
42508cdc2e
@ -3248,6 +3248,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
|
||||
} else {
|
||||
struct sctp_asconf_iterator *asc;
|
||||
struct sctp_laddr *wi;
|
||||
int ret;
|
||||
|
||||
SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
|
||||
sizeof(struct sctp_asconf_iterator),
|
||||
@ -3269,7 +3270,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
|
||||
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,
|
||||
ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
|
||||
sctp_asconf_iterator_stcb,
|
||||
sctp_asconf_iterator_ep_end,
|
||||
SCTP_PCB_ANY_FLAGS,
|
||||
@ -3277,6 +3278,12 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
|
||||
SCTP_ASOC_ANY_STATE,
|
||||
(void *)asc, 0,
|
||||
sctp_asconf_iterator_end, inp, 0);
|
||||
if (ret) {
|
||||
SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
|
||||
sctp_asconf_iterator_end(asc, 0);
|
||||
return (EFAULT);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
} else {
|
||||
|
@ -293,6 +293,9 @@ sctp_addr_change(struct ifaddr *ifa, int cmd)
|
||||
{
|
||||
uint32_t ifa_flags = 0;
|
||||
|
||||
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* BSD only has one VRF, if this changes we will need to hook in the
|
||||
* right things here to get the id to pass to the address managment
|
||||
|
@ -978,10 +978,7 @@ __FBSDID("$FreeBSD$");
|
||||
(((uint8_t *)&(a)->s_addr)[1] == 168)))
|
||||
|
||||
#define IN4_ISLOOPBACK_ADDRESS(a) \
|
||||
((((uint8_t *)&(a)->s_addr)[0] == 127) && \
|
||||
(((uint8_t *)&(a)->s_addr)[1] == 0) && \
|
||||
(((uint8_t *)&(a)->s_addr)[2] == 0) && \
|
||||
(((uint8_t *)&(a)->s_addr)[3] == 1))
|
||||
(((uint8_t *)&(a)->s_addr)[0] == 127)
|
||||
|
||||
#define IN4_ISLINKLOCAL_ADDRESS(a) \
|
||||
((((uint8_t *)&(a)->s_addr)[0] == 169) && \
|
||||
|
@ -365,8 +365,10 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
asoc->streamoutcnt = asoc->pre_open_streams;
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
asoc->strmout[i].state = SCTP_STREAM_OPEN;
|
||||
if (asoc->strmout) {
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
asoc->strmout[i].state = SCTP_STREAM_OPEN;
|
||||
}
|
||||
}
|
||||
/* EY - nr_sack: initialize highest tsn in nr_mapping_array */
|
||||
asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
|
||||
@ -909,7 +911,9 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
|
||||
if (stcb->sctp_socket) {
|
||||
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
|
||||
}
|
||||
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
|
||||
SCTP_SOCKET_UNLOCK(so, 1);
|
||||
#endif
|
||||
@ -4858,7 +4862,7 @@ __attribute__((noinline))
|
||||
if ((stcb) && (stcb->asoc.total_output_queue_size)) {
|
||||
;
|
||||
} else {
|
||||
if (locked_tcb != stcb) {
|
||||
if ((locked_tcb != NULL) && (locked_tcb != stcb)) {
|
||||
/* Very unlikely */
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
}
|
||||
|
@ -3222,12 +3222,14 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
|
||||
}
|
||||
}
|
||||
#ifdef INET
|
||||
if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) {
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
retried = 1;
|
||||
goto again_with_private_addresses_allowed;
|
||||
} else if (retried == 1) {
|
||||
stcb->asoc.scope.ipv4_local_scope = 0;
|
||||
if (stcb) {
|
||||
if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) {
|
||||
stcb->asoc.scope.ipv4_local_scope = 1;
|
||||
retried = 1;
|
||||
goto again_with_private_addresses_allowed;
|
||||
} else if (retried == 1) {
|
||||
stcb->asoc.scope.ipv4_local_scope = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
out:
|
||||
@ -10629,7 +10631,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
|
||||
* Clear all bits corresponding to TSNs
|
||||
* smaller or equal to the cumulative TSN.
|
||||
*/
|
||||
tsn_map &= (~0 << (1 - offset));
|
||||
tsn_map &= (~0U << (1 - offset));
|
||||
}
|
||||
selector = &sack_array[tsn_map];
|
||||
if (mergeable && selector->right_edge) {
|
||||
@ -10704,7 +10706,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
|
||||
* TSNs smaller or equal to the
|
||||
* cumulative TSN.
|
||||
*/
|
||||
tsn_map &= (~0 << (1 - offset));
|
||||
tsn_map &= (~0U << (1 - offset));
|
||||
}
|
||||
selector = &sack_array[tsn_map];
|
||||
if (mergeable && selector->right_edge) {
|
||||
|
@ -2785,6 +2785,45 @@ sctp_move_pcb_and_assoc(struct sctp_inpcb *old_inp, struct sctp_inpcb *new_inp,
|
||||
SCTP_INP_WUNLOCK(old_inp);
|
||||
}
|
||||
|
||||
/*
|
||||
* insert an laddr entry with the given ifa for the desired list
|
||||
*/
|
||||
static int
|
||||
sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act)
|
||||
{
|
||||
struct sctp_laddr *laddr;
|
||||
|
||||
laddr = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
|
||||
if (laddr == NULL) {
|
||||
/* out of memory? */
|
||||
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
SCTP_INCR_LADDR_COUNT();
|
||||
bzero(laddr, sizeof(*laddr));
|
||||
(void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
|
||||
laddr->ifa = ifa;
|
||||
laddr->action = act;
|
||||
atomic_add_int(&ifa->refcount, 1);
|
||||
/* insert it */
|
||||
LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an laddr entry from the local address list (on an assoc)
|
||||
*/
|
||||
static void
|
||||
sctp_remove_laddr(struct sctp_laddr *laddr)
|
||||
{
|
||||
|
||||
/* remove from the list */
|
||||
LIST_REMOVE(laddr, sctp_nxt_addr);
|
||||
sctp_free_ifa(laddr->ifa);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), laddr);
|
||||
SCTP_DECR_LADDR_COUNT();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5397,7 +5436,7 @@ sctp_select_primary_destination(struct sctp_tcb *stcb)
|
||||
|
||||
|
||||
/*
|
||||
* Delete the address from the endpoint local address list There is nothing
|
||||
* Delete the address from the endpoint local address list. There is nothing
|
||||
* to be done if we are bound to all addresses
|
||||
*/
|
||||
void
|
||||
@ -5448,8 +5487,7 @@ sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
|
||||
* to laddr
|
||||
*/
|
||||
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
|
||||
if (net->ro._s_addr &&
|
||||
(net->ro._s_addr->ifa == laddr->ifa)) {
|
||||
if (net->ro._s_addr == laddr->ifa) {
|
||||
/* Yep, purge src address selected */
|
||||
sctp_rtentry_t *rt;
|
||||
|
||||
@ -5512,46 +5550,6 @@ sctp_add_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* insert an laddr entry with the given ifa for the desired list
|
||||
*/
|
||||
int
|
||||
sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act)
|
||||
{
|
||||
struct sctp_laddr *laddr;
|
||||
|
||||
laddr = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
|
||||
if (laddr == NULL) {
|
||||
/* out of memory? */
|
||||
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
SCTP_INCR_LADDR_COUNT();
|
||||
bzero(laddr, sizeof(*laddr));
|
||||
(void)SCTP_GETTIME_TIMEVAL(&laddr->start_time);
|
||||
laddr->ifa = ifa;
|
||||
laddr->action = act;
|
||||
atomic_add_int(&ifa->refcount, 1);
|
||||
/* insert it */
|
||||
LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an laddr entry from the local address list (on an assoc)
|
||||
*/
|
||||
void
|
||||
sctp_remove_laddr(struct sctp_laddr *laddr)
|
||||
{
|
||||
|
||||
/* remove from the list */
|
||||
LIST_REMOVE(laddr, sctp_nxt_addr);
|
||||
sctp_free_ifa(laddr->ifa);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), laddr);
|
||||
SCTP_DECR_LADDR_COUNT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a local address from the TCB local address restricted list
|
||||
*/
|
||||
@ -5922,12 +5920,32 @@ sctp_pcb_finish(void)
|
||||
int i;
|
||||
struct sctp_iterator *it, *nit;
|
||||
|
||||
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
|
||||
SCTP_PRINTF("%s: race condition on teardown.\n", __func__);
|
||||
return;
|
||||
}
|
||||
SCTP_BASE_VAR(sctp_pcb_initialized) = 0;
|
||||
/*
|
||||
* In FreeBSD the iterator thread never exits but we do clean up.
|
||||
* The only way FreeBSD reaches here is if we have VRF's but we
|
||||
* still add the ifdef to make it compile on old versions.
|
||||
*/
|
||||
retry:
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
/*
|
||||
* sctp_iterator_worker() might be working on an it entry without
|
||||
* holding the lock. We won't find it on the list either and
|
||||
* continue and free/destroy it. While holding the lock, spin, to
|
||||
* avoid the race condition as sctp_iterator_worker() will have to
|
||||
* wait to re-aquire the lock.
|
||||
*/
|
||||
if (sctp_it_ctl.iterator_running != 0 || sctp_it_ctl.cur_it != NULL) {
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
SCTP_PRINTF("%s: Iterator running while we held the lock. Retry. "
|
||||
"cur_it=%p\n", __func__, sctp_it_ctl.cur_it);
|
||||
DELAY(10);
|
||||
goto retry;
|
||||
}
|
||||
TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
|
||||
if (it->vn != curvnet) {
|
||||
continue;
|
||||
@ -5945,7 +5963,7 @@ sctp_pcb_finish(void)
|
||||
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
|
||||
}
|
||||
SCTP_ITERATOR_UNLOCK();
|
||||
SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
|
||||
SCTP_OS_TIMER_STOP_DRAIN(&SCTP_BASE_INFO(addr_wq_timer.timer));
|
||||
SCTP_WQ_ADDR_LOCK();
|
||||
LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
|
||||
LIST_REMOVE(wi, sctp_nxt_addr);
|
||||
@ -6012,6 +6030,14 @@ sctp_pcb_finish(void)
|
||||
|
||||
SCTP_WQ_ADDR_DESTROY();
|
||||
|
||||
/* Get rid of other stuff too. */
|
||||
if (SCTP_BASE_INFO(sctp_asochash) != NULL)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_asochash), SCTP_BASE_INFO(hashasocmark));
|
||||
if (SCTP_BASE_INFO(sctp_ephash) != NULL)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_ephash), SCTP_BASE_INFO(hashmark));
|
||||
if (SCTP_BASE_INFO(sctp_tcpephash) != NULL)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_tcpephash), SCTP_BASE_INFO(hashtcpmark));
|
||||
|
||||
SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_ep));
|
||||
SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asoc));
|
||||
SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_laddr));
|
||||
@ -6021,13 +6047,6 @@ sctp_pcb_finish(void)
|
||||
SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_strmoq));
|
||||
SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf));
|
||||
SCTP_ZONE_DESTROY(SCTP_BASE_INFO(ipi_zone_asconf_ack));
|
||||
/* Get rid of other stuff to */
|
||||
if (SCTP_BASE_INFO(sctp_asochash) != NULL)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_asochash), SCTP_BASE_INFO(hashasocmark));
|
||||
if (SCTP_BASE_INFO(sctp_ephash) != NULL)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_ephash), SCTP_BASE_INFO(hashmark));
|
||||
if (SCTP_BASE_INFO(sctp_tcpephash) != NULL)
|
||||
SCTP_HASH_FREE(SCTP_BASE_INFO(sctp_tcpephash), SCTP_BASE_INFO(hashtcpmark));
|
||||
#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
|
||||
SCTP_FREE(SCTP_BASE_STATS, SCTP_M_MCORE);
|
||||
#endif
|
||||
@ -6991,6 +7010,11 @@ sctp_initiate_iterator(inp_func inpf,
|
||||
if (af == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
|
||||
SCTP_PRINTF("%s: abort on initialize being %d\n", __func__,
|
||||
SCTP_BASE_VAR(sctp_pcb_initialized));
|
||||
return (-1);
|
||||
}
|
||||
SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
|
||||
SCTP_M_ITER);
|
||||
if (it == NULL) {
|
||||
@ -7029,7 +7053,13 @@ sctp_initiate_iterator(inp_func inpf,
|
||||
|
||||
}
|
||||
SCTP_IPI_ITERATOR_WQ_LOCK();
|
||||
|
||||
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
SCTP_PRINTF("%s: rollback on initialize being %d it=%p\n", __func__,
|
||||
SCTP_BASE_VAR(sctp_pcb_initialized), it);
|
||||
SCTP_FREE(it, SCTP_M_ITER);
|
||||
return (-1);
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
|
||||
if (sctp_it_ctl.iterator_running == 0) {
|
||||
sctp_wakeup_iterator();
|
||||
|
@ -598,10 +598,6 @@ void
|
||||
|
||||
void sctp_add_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *, uint32_t);
|
||||
|
||||
int sctp_insert_laddr(struct sctpladdr *, struct sctp_ifa *, uint32_t);
|
||||
|
||||
void sctp_remove_laddr(struct sctp_laddr *);
|
||||
|
||||
void sctp_del_local_addr_ep(struct sctp_inpcb *, struct sctp_ifa *);
|
||||
|
||||
int sctp_add_remote_addr(struct sctp_tcb *, struct sockaddr *, struct sctp_nets **, int, int);
|
||||
|
@ -85,7 +85,7 @@ sctp_audit_retranmission_queue(struct sctp_association *asoc)
|
||||
asoc->sent_queue_cnt);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net, uint16_t threshold)
|
||||
{
|
||||
@ -111,9 +111,9 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
net->last_active = sctp_get_tick_count();
|
||||
sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
|
||||
stcb->sctp_ep, stcb, net,
|
||||
inp, stcb, net,
|
||||
SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,10 +45,6 @@ struct sctp_nets *
|
||||
sctp_find_alternate_net(struct sctp_tcb *,
|
||||
struct sctp_nets *, int mode);
|
||||
|
||||
int
|
||||
sctp_threshold_management(struct sctp_inpcb *, struct sctp_tcb *,
|
||||
struct sctp_nets *, uint16_t);
|
||||
|
||||
int
|
||||
sctp_t3rxt_timer(struct sctp_inpcb *, struct sctp_tcb *,
|
||||
struct sctp_nets *);
|
||||
|
@ -1470,7 +1470,9 @@ sctp_handle_addr_wq(void)
|
||||
if (asc->cnt == 0) {
|
||||
SCTP_FREE(asc, SCTP_M_ASC_IT);
|
||||
} else {
|
||||
(void)sctp_initiate_iterator(sctp_asconf_iterator_ep,
|
||||
int ret;
|
||||
|
||||
ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
|
||||
sctp_asconf_iterator_stcb,
|
||||
NULL, /* No ep end for boundall */
|
||||
SCTP_PCB_FLAGS_BOUNDALL,
|
||||
@ -1478,6 +1480,23 @@ sctp_handle_addr_wq(void)
|
||||
SCTP_ASOC_ANY_STATE,
|
||||
(void *)asc, 0,
|
||||
sctp_asconf_iterator_end, NULL, 0);
|
||||
if (ret) {
|
||||
SCTP_PRINTF("Failed to initiate iterator for handle_addr_wq\n");
|
||||
/*
|
||||
* Freeing if we are stopping or put back on the
|
||||
* addr_wq.
|
||||
*/
|
||||
if (SCTP_BASE_VAR(sctp_pcb_initialized) == 0) {
|
||||
sctp_asconf_iterator_end(asc, 0);
|
||||
} else {
|
||||
SCTP_WQ_ADDR_LOCK();
|
||||
LIST_FOREACH(wi, &asc->list_of_work, sctp_nxt_addr) {
|
||||
LIST_INSERT_HEAD(&SCTP_BASE_INFO(addr_wq), wi, sctp_nxt_addr);
|
||||
}
|
||||
SCTP_WQ_ADDR_UNLOCK();
|
||||
SCTP_FREE(asc, SCTP_M_ASC_IT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1012,10 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
|
||||
stcb = LIST_FIRST(&inp->sctp_asoc_list);
|
||||
if (stcb == NULL) {
|
||||
goto notConn6;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
fnd = 0;
|
||||
sin_a6 = NULL;
|
||||
@ -1029,7 +1032,10 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
}
|
||||
if ((!fnd) || (sin_a6 == NULL)) {
|
||||
/* punt */
|
||||
goto notConn6;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_FREE_SONAME(sin6);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
vrf_id = inp->def_vrf_id;
|
||||
sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *) & net->ro, net, 0, vrf_id);
|
||||
@ -1038,7 +1044,6 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
||||
}
|
||||
} else {
|
||||
/* For the bound all case you get back 0 */
|
||||
notConn6:
|
||||
memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
|
||||
}
|
||||
} else {
|
||||
@ -1139,10 +1144,6 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
|
||||
static int
|
||||
sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
|
||||
{
|
||||
#ifdef INET
|
||||
struct sockaddr *addr;
|
||||
|
||||
#endif
|
||||
struct in6pcb *inp6 = sotoin6pcb(so);
|
||||
int error;
|
||||
|
||||
@ -1154,19 +1155,21 @@ sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
|
||||
error = sctp6_getaddr(so, nam);
|
||||
#ifdef INET
|
||||
if (error) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
/* try v4 next if v6 failed */
|
||||
error = sctp_ingetaddr(so, nam);
|
||||
if (error) {
|
||||
return (error);
|
||||
}
|
||||
addr = *nam;
|
||||
/* if I'm V6ONLY, convert it to v4-mapped */
|
||||
if (SCTP_IPV6_V6ONLY(inp6)) {
|
||||
struct sockaddr_in6 sin6;
|
||||
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
|
||||
memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL) {
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
return (ENOMEM);
|
||||
}
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
*nam = (struct sockaddr *)sin6;
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
@ -1176,10 +1179,6 @@ sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
|
||||
static int
|
||||
sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
||||
{
|
||||
#ifdef INET
|
||||
struct sockaddr *addr;
|
||||
|
||||
#endif
|
||||
struct in6pcb *inp6 = sotoin6pcb(so);
|
||||
int error;
|
||||
|
||||
@ -1191,19 +1190,21 @@ sctp6_getpeeraddr(struct socket *so, struct sockaddr **nam)
|
||||
error = sctp6_peeraddr(so, nam);
|
||||
#ifdef INET
|
||||
if (error) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
/* try v4 next if v6 failed */
|
||||
error = sctp_peeraddr(so, nam);
|
||||
if (error) {
|
||||
return (error);
|
||||
}
|
||||
addr = *nam;
|
||||
/* if I'm V6ONLY, convert it to v4-mapped */
|
||||
if (SCTP_IPV6_V6ONLY(inp6)) {
|
||||
struct sockaddr_in6 sin6;
|
||||
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
|
||||
memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL) {
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
return (ENOMEM);
|
||||
}
|
||||
in6_sin_2_v4mapsin6((struct sockaddr_in *)*nam, sin6);
|
||||
SCTP_FREE_SONAME(*nam);
|
||||
*nam = (struct sockaddr *)sin6;
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
|
Loading…
Reference in New Issue
Block a user