Skip to content

Commit

Permalink
Provide 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 not be
valid or dealocated.
To let application know when they can safetely deallocate memory
registered with an association, we are storing a destroy function which
will be used for usrsctp to notify application when the association is
gone.
Related issues:
sctplab#405
sctplab#147
  • Loading branch information
sancane committed Oct 11, 2020
1 parent 53579be commit 76ef479
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 3 deletions.
17 changes: 17 additions & 0 deletions usrsctplib/netinet/sctp_pcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,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 @@ -535,6 +542,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 @@ -690,6 +706,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
8 changes: 8 additions & 0 deletions usrsctplib/netinet/sctp_pcb.h
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 @@ -708,6 +709,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
13 changes: 10 additions & 3 deletions usrsctplib/user_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -3139,7 +3139,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 @@ -3150,15 +3150,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
3 changes: 3 additions & 0 deletions usrsctplib/usrsctp.h
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 76ef479

Please sign in to comment.