Re: Unable to call SCTP_ADD_STREAMS twice?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



That worked perfectly.

Thanks!

On Mon, Jul 1, 2019 at 4:29 AM Xin Long <lucien.xin@xxxxxxxxx> wrote:
>
> On Sat, Jun 29, 2019 at 4:34 AM TJ Corley <tjcorley30@xxxxxxxxx> wrote:
> >
> > I am creating a library and it appears I am unable to call setsockopt
> > with the option SCTP_ADD_STREAMS on the same same socket twice. On the
> > second attempt it will return EINPROGRESS no matter what. It appears
> > this is happening due to the fact that
> > asoc->strreset_outstanding is still set. However if I am reading the
> > code correctly when I call the socket option sctp_send_reconf will be
> > called with a param of type SCTP_PARAM_RESET_ADD_OUT_STREAMS which
> > should eventually trigger the chain of  sctp_sf_do_reconf
> > ->sctp_process_strreset_outreq which will decrement
> > asoc->strreset_outstanding.
> >
> > I have SCTP_RECONFIG_SUPPORTED enabled and SCTP_ENABLE_RESET set to
> > SCTP_ENABLE_CHANGE_ASSOC_REQ | SCTP_ENABLE_RESET_STREAM_REQ |
> > SCTP_ENABLE_RESET_ASSOC_REQ on all the relevant sockets. Is there
> > anything else I should be doing?
> Yes, you need to do:
>
> # sysctl -w net.sctp.reconf_enable=1
>
> which is like a main switch for all sctp socket.
>
> >
> > I have included my sample code below that triggers this behavior.
> >
> > Thanks for all the help,
> >
> > TJ
> >
> > #include <arpa/inet.h>
> > #include <errno.h>
> > #include <linux/sctp.h>
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <string.h>
> > #include <sys/socket.h>
> > #include <sys/uio.h>
> > #include <unistd.h>
> >
> > int allow_reconfigure_support(int fd) {
> >   struct sctp_assoc_value params;
> >
> >   params.assoc_value = 1;
> >   params.assoc_id = 0;
> >   return setsockopt(fd, IPPROTO_SCTP, SCTP_RECONFIG_SUPPORTED, &params,
> >                     sizeof(params));
> > }
> >
> > int allow_reset(int fd) {
> >
> >   struct sctp_assoc_value params;
> >
> >   params.assoc_id = 0;
> >   params.assoc_value = SCTP_ENABLE_CHANGE_ASSOC_REQ |
> >                        SCTP_ENABLE_RESET_STREAM_REQ |
> >                        SCTP_ENABLE_RESET_ASSOC_REQ;
> >
> >   return setsockopt(fd, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &params,
> >                     sizeof(params));
> > }
> >
> > int add_streams(int fd, int num_streams) {
> >
> >   struct sctp_add_streams addstr;
> >   addstr.sas_outstrms = num_streams;
> >   addstr.sas_instrms = 0x00;
> >   addstr.sas_assoc_id = 0;
> >
> >   return setsockopt(fd, IPPROTO_SCTP, SCTP_ADD_STREAMS, &addstr,
> >                     sizeof(addstr));
> > }
> >
> > int main() {
> >   struct sockaddr_in in, out;
> >   socklen_t out_len;
> >   int server;
> >   int client;
> >   int accept_fd;
> >   int err;
> >   memset(&in, '\x00', sizeof(in));
> >
> >   in.sin_family = AF_INET;
> >   in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
> >   in.sin_port = htons(12346);
> >
> >   server = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
> >   client = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
> >
> >   if (server == -1 || client == -1) {
> >     printf("socket(): %s\n", strerror(errno));
> >     return -1;
> >   }
> >
> >   if (allow_reconfigure_support(server)) {
> >     printf("server allow_reconfigure_support: %s\n", strerror(errno));
> >   }
> >
> >   if (allow_reset(client)) {
> >     printf("client allow_reset: %s\n", strerror(errno));
> >   }
> >
> >   if (allow_reconfigure_support(client)) {
> >     printf("client allow_reconfigure_support: %s\n", strerror(errno));
> >   }
> >
> >   if (allow_reset(client)) {
> >     printf("client allow_reset: %s\n", strerror(errno));
> >   }
> >
> >   printf("server fd: %d\n", server);
> >   printf("client fd: %d\n", client);
> >
> >   err = bind(server, (void *)&in, sizeof(in));
> >   if (err == -1) {
> >     printf("bind: %s\n", strerror(errno));
> >     return -1;
> >   }
> >
> >   err = listen(server, 1);
> >   if (err == -1) {
> >     printf("listen: %s\n", strerror(errno));
> >     return -1;
> >   }
> >
> >   err = connect(client, (void *)&in, sizeof(in));
> >   if (err == -1) {
> >     printf("connect: %s\n", strerror(errno));
> >     return -1;
> >   }
> >
> >   accept_fd = accept(server, (void *)&out, &out_len);
> >   if (accept_fd == -1) {
> >     printf("accept: %s\n", strerror(errno));
> >     return -1;
> >   }
> >   printf("accept_fd: %d\n", accept_fd);
> >
> >   if (allow_reconfigure_support(accept_fd)) {
> >     printf("accept_fd allow_reconfigure_support: %s\n", strerror(errno));
> >   }
> >
> >   if (allow_reset(accept_fd)) {
> >     printf("accept_fd allow_reset: %s\n", strerror(errno));
> >   }
> >
> >   err = add_streams(accept_fd, 0x10);
> >   if (err == -1) {
> >     printf("add_streams: %s\n", strerror(errno));
> >     return -1;
> >   }
> >
> >   sleep(1);
> >
> >   err = add_streams(accept_fd, 0x10);
> >   if (err == -1) {
> >     printf("add_streams2: %s\n", strerror(errno));
> >     return -1;
> >   }
> >
> >   printf("finished no errors\n");
> > }



[Index of Archives]     [Linux Networking Development]     [Linux OMAP]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux