Improve sctp_get[lp]addrs
@@ -2695,22 +2695,26 @@ usrsctp_getpaddrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
{
struct sctp_getaddresses *addrs;
struct sockaddr *sa;
- sctp_assoc_t asoc;
caddr_t lim;
socklen_t opt_len;
+ uint32_t size_of_addresses;
int cnt;
if (raddrs == NULL) {
errno = EFAULT;
return (-1);
}
- asoc = id;
- opt_len = (socklen_t)sizeof(sctp_assoc_t);
- if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, &asoc, &opt_len) != 0) {
+ /* When calling getsockopt(), the value contains the assoc_id. */
+ size_of_addresses = (uint32_t)id;
+ opt_len = (socklen_t)sizeof(uint32_t);
+ if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, &size_of_addresses, &opt_len) != 0) {
+ if (errno == ENOENT) {
+ return (0);
+ } else {
return (-1);
}
- /* size required is returned in 'asoc' */
- opt_len = (socklen_t)((size_t)asoc + sizeof(struct sctp_getaddresses));
+ }
+ opt_len = (socklen_t)((size_t)size_of_addresses + sizeof(struct sctp_getaddresses));
addrs = calloc(1, (size_t)opt_len);
if (addrs == NULL) {
errno = ENOMEM;
@@ -2770,10 +2774,10 @@ int
usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
{
struct sctp_getaddresses *addrs;
- caddr_t lim;
struct sockaddr *sa;
- size_t size_of_addresses;
+ caddr_t lim;
socklen_t opt_len;
+ uint32_t size_of_addresses;
int cnt;
if (raddrs == NULL) {
@@ -2781,13 +2785,8 @@ usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
return (-1);
}
size_of_addresses = 0;
- opt_len = (socklen_t)sizeof(int);
+ opt_len = (socklen_t)sizeof(uint32_t);
if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDR_SIZE, &size_of_addresses, &opt_len) != 0) {
- errno = ENOMEM;
- return (-1);
- }
- if (size_of_addresses == 0) {
- errno = ENOTCONN;
return (-1);
}
opt_len = (socklen_t)(size_of_addresses + sizeof(struct sctp_getaddresses));
@@ -2800,9 +2799,12 @@ usrsctp_getladdrs(struct socket *so, sctp_assoc_t id, struct sockaddr **raddrs)
/* Now lets get the array of addresses */
if (usrsctp_getsockopt(so, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs, &opt_len) != 0) {
free(addrs);
- errno = ENOMEM;
return (-1);
}
+ if (size_of_addresses == 0) {
+ free(addrs);
+ return (0);
+ }
*raddrs = &addrs->addr[0].sa;
cnt = 0;
sa = &addrs->addr[0].sa;
