This is the default, for backwards compatibility reasons.
.RE
.TP
+.B rtp_mtu_discovery \fIOPTION\fR
+Control whether the system attemps path-MTU discovery using RTP packets
+transmitted over IPv4. (This is not configurable in IPv6.) Possible values
+are:
+.RS
+.TP
+.B default
+Do whatever the kernel usually does with UDP packets. This is, err, the
+default.
+.TP
+.B yes
+Force path-MTU disocvery. The `don't fragment' bit is set on outgoing packets
+and we assume that the kernel will handle ICMP `fragmentation needed' errors
+coming back and fragment accordingly.
+.TP
+.B no
+Disable path-MTU discovery. Packets will be sent without the `don't fragment'
+bit, and routers will be expected to fragment packets as necessary.
+.RE
+.IP
+This option is experimental, and may change or be removed in a future release.
+.TP
.B rtp_rcvbuf \fISIZE\fR
Set
.BR disorder-playrtp (1)'s
return -1;
}
+/** @brief Validate an MTU-discovery setting
+ * @param cs Configuration state
+ * @param nvec Length of (proposed) new value
+ * @param vec Elements of new value
+ * @return 0 on success, non-0 on error
+ */
+static int validate_mtu_discovery(const struct config_state attribute((unused)) *cs,
+ int nvec,
+ char **vec) {
+ if (nvec == 1 &&
+ (!strcmp(vec[0], "default") ||
+ !strcmp(vec[0], "yes") ||
+ !strcmp(vec[0], "no")))
+ return 0;
+ disorder_error(0, "%s:%d: invalid MTU-discovery setting", cs->path, cs->line);
+ return -1;
+}
+
/** @brief Validate a destination network address
* @param cs Configuration state
* @param nvec Length of (proposed) new value
{ C(rtp_maxbuffer), &type_integer, validate_non_negative },
{ C(rtp_minbuffer), &type_integer, validate_non_negative },
{ C(rtp_mode), &type_string, validate_any },
+ { C(rtp_mtu_discovery), &type_string, validate_mtu_discovery },
{ C(rtp_rcvbuf), &type_integer, validate_non_negative },
{ C(rtp_request_address), &type_netaddress, validate_inetaddr },
{ C(rtp_verbose), &type_boolean, validate_any },
c->connect.af = -1;
c->rtp_mode = xstrdup("auto");
c->rtp_max_payload = -1;
+ c->rtp_mtu_discovery = xstrdup("default");
return c;
}
*/
long rtp_max_payload;
+ /** @brief Whether to allow MTU discovery
+ *
+ * This is `yes' to force it on, `no' to force it off, or `default' to do
+ * whatever the system is configured to do. Note that this only has a
+ * useful effect in IPv4, since IPv6 doesn't permit hop-by-hop
+ * fragmentation.
+ */
+ char *rtp_mtu_discovery;
+
/** @brief Login lifetime in seconds */
long cookie_login_lifetime;
"multicast-loop",
"rtp-mode",
"rtp-max-payload",
+ "rtp-mtu-discovery",
NULL
};
static const int one = 1;
struct netaddress dst[1], src[1];
const char *mode;
+#ifdef IP_MTU_DISCOVER
+ const char *mtu_disc;
+ int opt;
+#endif
/* Get the mode */
mode = uaudio_get("rtp-mode", "auto");
disorder_fatal(errno, "error connecting broadcast socket to %s",
format_sockaddr(dres->ai_addr));
}
+#ifdef IP_MTU_DISCOVER
+ mtu_disc = uaudio_get("rtp-mtu-discovery", "default");
+ do {
+ if(!strcmp(mtu_disc, "yes")) opt = IP_PMTUDISC_DO;
+ else if(!strcmp(mtu_disc, "no")) opt = IP_PMTUDISC_DONT;
+ else break;
+ if(setsockopt(rtp_fd4, IPPROTO_IP, IP_MTU_DISCOVER, &opt, sizeof opt))
+ disorder_fatal(errno, "error setting MTU discovery");
+ if(sres->ai_family == AF_INET &&
+ setsockopt(rtp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &opt, sizeof opt))
+ disorder_fatal(errno, "error setting MTU discovery");
+ } while (0);
+#endif
if(config->rtp_verbose)
disorder_info("RTP: prepared socket");
}
uaudio_set("multicast-loop", config->multicast_loop ? "yes" : "no");
snprintf(buffer, sizeof buffer, "%ld", config->rtp_max_payload);
uaudio_set("rtp-max-payload", buffer);
+ uaudio_set("rtp-mtu-discovery", config->rtp_mtu_discovery);
if(config->rtp_verbose)
disorder_info("RTP: configured");
}