Skip to content

Commit

Permalink
Provide a destroy function for registered addresses
Browse files Browse the repository at this point in the history
This patch tries to fix the problem of usrsctp calling callbacks even
after the usrsctp_close function is invoked.
Usrsctp seems to keep the asociation around until the teardown procedure
is completed. The problem is that sometimes it is not possible to
complete the shutdown procedure if the lower transport is gone like SCTP
running on top of DTLS. In such case, callbacks triggered from usrsctp
are providing an pointer address to an applications which could have
been deallocated.
To let applications know when they can safely deallocate memory
registered with an association, we are storing a destroy function which
will be used for usrsctp to notify applications when the association is
gone.
Related issues:
sctplab/usrsctp#405
sctplab/usrsctp#147

From: sctplab/usrsctp#535
  • Loading branch information
Tulio Beloqui committed Jun 23, 2023
1 parent 0e20dd0 commit d850ebb
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,13 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap)
if (sctp_ifap->ifn_p) {
sctp_free_ifn(sctp_ifap->ifn_p);
}
if (sctp_ifap->destroy_address) {
/* sctp_ifap->address is struct sockaddr_conn */
if (sctp_ifap->address.sconn.sconn_addr) {
sctp_ifap->destroy_address (sctp_ifap->address.sconn.sconn_addr);
}
sctp_ifap->address.sconn.sconn_addr = NULL;
}
SCTP_FREE(sctp_ifap, SCTP_M_IFA);
atomic_subtract_int(&SCTP_BASE_INFO(ipi_count_ifas), 1);
}
Expand Down Expand Up @@ -549,6 +556,15 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
uint32_t ifn_type, const char *if_name, void *ifa,
struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add)
{
return sctp_add_addr_to_vrf_full (vrf_id, ifn, ifn_index, ifn_type, if_name, ifa, addr, ifa_flags, dynamic_add, NULL);
}

struct sctp_ifa *
sctp_add_addr_to_vrf_full(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
uint32_t ifn_type, const char *if_name, void *ifa,
struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add, void (*destroy)(void *))
{
struct sctp_vrf *vrf;
struct sctp_ifn *sctp_ifnp, *new_sctp_ifnp;
Expand Down Expand Up @@ -704,6 +720,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
#endif
sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE;
sctp_ifap->flags = ifa_flags;
sctp_ifap->destroy_address = destroy;
/* Set scope */
switch (sctp_ifap->address.sa.sa_family) {
#ifdef INET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ struct sctp_ifa {
* appropriate locks. This is for V6.
*/
union sctp_sockstore address;
void (*destroy_address)(void *);
uint32_t refcount; /* number of folks referring to this */
uint32_t flags;
uint32_t localifa_flags;
Expand Down Expand Up @@ -715,6 +716,13 @@ sctp_add_addr_to_vrf(uint32_t vrfid,
void *ifa, struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add);

struct sctp_ifa *
sctp_add_addr_to_vrf_full(uint32_t vrfid,
void *ifn, uint32_t ifn_index, uint32_t ifn_type,
const char *if_name,
void *ifa, struct sockaddr *addr, uint32_t ifa_flags,
int dynamic_add, void (*destroy)(void *));

void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu);

void sctp_free_ifn(struct sctp_ifn *sctp_ifnp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3141,7 +3141,7 @@ void sctp_userspace_ip6_output(int *result, struct mbuf *o_pak,
#endif

void
usrsctp_register_address(void *addr)
usrsctp_register_address_full(void *addr, void (*destroy)(void *))
{
struct sockaddr_conn sconn;

Expand All @@ -3152,15 +3152,22 @@ usrsctp_register_address(void *addr)
#endif
sconn.sconn_port = 0;
sconn.sconn_addr = addr;
sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID,
sctp_add_addr_to_vrf_full(SCTP_DEFAULT_VRFID,
NULL,
0xffffffff,
0,
"conn",
NULL,
(struct sockaddr *)&sconn,
0,
0);
0,
destroy);
}

void
usrsctp_register_address(void *addr)
{
usrsctp_register_address_full (addr, NULL);
}

void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,9 @@ usrsctp_get_non_blocking(struct socket *);
void
usrsctp_register_address(void *);

void
usrsctp_register_address_full(void *, void (*)(void *));

void
usrsctp_deregister_address(void *);

Expand Down

0 comments on commit d850ebb

Please sign in to comment.