shithub: riscv

Download patch

ref: 38a8af2d72c44bde3f47127a273c864a23480849
parent: 04c3a6f66e3b895a087124ed415f01e23e21ee10
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Mar 28 12:58:09 EDT 2016

devip: applying changes for bug: multicasts_and_udp_buffers

/n/bugs/open/multicasts_and_udp_buffers
http://bugs.9front.org/open/multicasts_and_udp_buffers/readme

michal@Lnet.pl

I have ported my small MPEG-TS analisis tool to Plan9.

To allow this application working I had to fix a bug in the kernel IPv4 code and increase UDP input buffer.

Bug is related to listening for IPv4 multicast traffic. There is no problem if you listen for only one group or multiple groups with different UDP ports. This works:

Write to UDP ctl:

anounce PORT
addmulti INTERFACE_ADDR MULTICAST_ADDR
headers

and you can read packets from data file.

You need to set headers option because otherwise every UDP packet for MULTICAST_ADDR!PORT is treat as separate connection. This is a bug and should be fixed too, but I didn't tried it.

There is a problem when you need to receive packets for multiple multicast groups. Usually the same destination port is used by multiple streams and above sequence of commands fails for second group because the port is the same.

Simple and probably non-intrusive fix is adding "|| ipismulticast(addr)" to if statement at /sys/src/9/ip/devip.c:861 line:

if(ipforme(c->p->f, addr) || ipismulticast(addr))

This fixes the problem and now you can use the following sequence to listen for multiple multicast groups even if they all have the same destination port:

announce MULTICAST_ADDR!PORT
addmulti INTERFACE_ADDR MULTICAST_ADDR
headers

After that my application started working but signals packet drops at >2 Mb/s input rate. The same is reported by kernel netlog. Increase capacity of UDP connection input queue fixes this problem /sys/src/9/ip/udp.c:153

c->rq = qopen(512*1024, Qmsg, 0, 0);

--
Michał Derkacz

--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -858,7 +858,7 @@
 		else {
 			if(parseip(addr, str) == -1)
 				return Ebadip;
-			if(ipforme(c->p->f, addr))
+			if(ipforme(c->p->f, addr) || ipismulticast(addr))
 				ipmove(c->laddr, addr);
 			else
 				return "not a local IP address";
--- a/sys/src/9/ip/udp.c
+++ b/sys/src/9/ip/udp.c
@@ -150,7 +150,7 @@
 static void
 udpcreate(Conv *c)
 {
-	c->rq = qopen(128*1024, Qmsg, 0, 0);
+	c->rq = qopen(512*1024, Qmsg, 0, 0);
 	c->wq = qbypass(udpkick, c);
 }