Date: Fri, 17 Jul 2020 20:21:06 +0200 From: Bernd Walter <ticso@cicely7.cicely.de> To: Michael Tuexen <Michael.Tuexen@lurchi.franken.de> Cc: ticso@cicely.de, freebsd-net@freebsd.org, Bernd Walter <ticso@cicely7.cicely.de> Subject: Re: SCTP problem, how to debug? Message-ID: <20200717182106.GC79604@cicely7.cicely.de> In-Reply-To: <20200717175055.GB79604@cicely7.cicely.de> References: <20200717160739.GA79604@cicely7.cicely.de> <EE7DEB1F-D941-4FC2-91FB-7A1A3D3E11C3@lurchi.franken.de> <20200717175055.GB79604@cicely7.cicely.de>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Jul 17, 2020 at 07:50:55PM +0200, Bernd Walter wrote: > On Fri, Jul 17, 2020 at 07:27:00PM +0200, Michael Tuexen wrote: > > > > > > > On 17. Jul 2020, at 18:07, Bernd Walter <ticso@cicely7.cicely.de> wrote: > > > > > > I'm running an LED matrix with SCTP. > > > The matrix consists from 24 raspberry pi running NFS-root FreeBSD > > > 12.0-RELEASE (they have an SD card for u-boot and loader). > > > A client system is running FreeBSD 12.1-RELEASE. > > I fixed iterator related bugs and this was MFCed to stable/12 recently. > > The problem was that the iterator stopped sending. > > The client side should be easy to update. > The modules can be a bit more tricky, but I will try. > > > > > > > The matrix modules have a one to many service socket. > > > The daemon regularily sends status informations (temperature, etc.) to > > > each association and has a second thread to receive. > > > > > > The client system has two deamons running. > > > > > > One daemon is to control power output related to temperature states. > > > It has one thread reestablishing associations via sctp_connectx() to > > > each of the 24 modules using a single one to many socket. > > > Another thread collects all regular received data and updates stored > > > values. > > > Yet another thread sends power control data via SCTP_SENDALL, so that all modules know > > > the maxed allowed brightness rating. > > > > > > The other daemon uses the same threads to reconnect and receive. > > > It connects to the very same sockets on the modules. > > > Another thread updates picture data and wanted power rating. > > > That is sending picture data to the given matrix module and then > > > SCTP_SENDALL an update trigger to all modules. > > > That is reduced brightness at night times, ... > > > > > > All SCTP_SENDALL are just trigger with 0 length and different ppid values. > > Are you really sending messages of length 0? That shouldn't work... > > No - I was wrong. > Just checked and I do send a dummy byte: > void > apa_push_leds() > { > // send dummy content, because we wouldn't send anything without > char message = 0; > send_message(&message, 1, 0, 0x00000002, SCTP_SENDALL); > } > > send_message(const void* data, size_t len, uint32_t stream, uint32_t ppid, uint32_t flags, const String& dest = "") > { > Mutex::Guard mtx(sctp_mtx); > ssize_t remain = len; > > if (!dest.empty()) { > struct addrinfo ai; > struct addrinfo *lips; > bzero(&ai, sizeof(ai)); > ai.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; > ai.ai_family = AF_INET6; > ai.ai_protocol = IPPROTO_SCTP; > ai.ai_socktype = SOCK_SEQPACKET; > int res = 0; > String sport = port; > String addr = dest; > res = getaddrinfo(addr.c_str(), sport.c_str(), &ai, &lips); > if (res != 0) { > throw Error("failed to resolve local ips"); > } > struct addrinfo *lip; > for (lip = lips; lip && remain > 0; lip = lip->ai_next) { > while (remain > 0) { > ssize_t res; > res = sctp_sendmsgx(sctp_socket, ((uint8_t*)data) + (len - remain), remain, lip->ai_addr, 1, ppid, flags | SCTP_EOR, stream, 0, 0); I know that I could use all resolved addresses in one call. In this case it is just a single IP address. Might change that later nonethelesss to have better example code for other needs. > if (res > 0) { > remain -= res; > } else { > if (errno != EAGAIN && errno != ENOBUFS) { Just fixed that posssible addrinfo leak. Don't think that is the issue here though. > return; > } else { > int res; > do { > struct pollfd pfd; > pfd.fd = sctp_socket; > pfd.events = POLLOUT; > pfd.revents = 0; > res = poll(&pfd, 1, 5000); > } while (res == 0); > } > } > } > } > freeaddrinfo(lips); > } else { > while (remain > 0) { > ssize_t res; > res = sctp_sendmsg(sctp_socket, ((uint8_t*)data) + (len - remain), remain, NULL, 0, ppid, flags | SCTP_EOR, stream, 0, 0); > if (res > 0) { > remain -= res; > } else { > if (errno != EAGAIN && errno != ENOBUFS) { > return; > } else { > int res; > do { > struct pollfd pfd; > pfd.fd = sctp_socket; > pfd.events = POLLOUT; > pfd.revents = 0; > res = poll(&pfd, 1, 5000); > } while (res == 0); > } > } > } > } > } > -- B.Walter <bernd@bwct.de> http://www.bwct.de Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20200717182106.GC79604>