+
+static int parse_fec_parms(const char *arg, struct sender_command_data *scd)
+{
+ int32_t val;
+ char *a = para_strdup(arg),
+ *b = strchr(a, ':'),
+ *c = strrchr(a, ':');
+ int ret = -E_COMMAND_SYNTAX;
+
+ if (!b || !c)
+ goto out;
+ *b = *c = '\0';
+
+ ret = para_atoi32(a, &val);
+ if (ret < 0)
+ goto out;
+
+ /* optional max_slice_bytes (0 means "use MTU") */
+ if (b == c) {
+ scd->max_slice_bytes = 0;
+ } else {
+ if (val < 0 || val > 65535)
+ goto fec_einval;
+ scd->max_slice_bytes = val;
+
+ ret = para_atoi32(b + 1, &val);
+ if (ret < 0)
+ goto out;
+ }
+
+ /* k = data_slices_per_group */
+ if (val < 0 || val > 255)
+ goto fec_einval;
+ scd->data_slices_per_group = val;
+
+ /* n = slices_per_group */
+ ret = para_atoi32(c + 1, &val);
+ if (ret < 0)
+ goto out;
+ if (val < 0 || val < scd->data_slices_per_group)
+ goto fec_einval;
+ scd->slices_per_group = val;
+ ret = 0;
+out:
+ free(a);
+ return ret;
+fec_einval:
+ ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+ goto out;
+}
+
+/**
+ * Parse a FEC URL string.
+ *
+ * \param arg the URL string to parse.
+ * \param scd The structure containing host, port and the FEC parameters.
+ *
+ * \return Standard.
+ *
+ * A FEC URL consists of an ordinary URL string according to RFC 3986,
+ * optionally followed by a slash and the three FEC parameters slice_size,
+ * data_slices_per_group and slices_per_group. The three FEC parameters are
+ * separated by colons.
+ *
+ * \sa \ref parse_url().
+ */
+int parse_fec_url(const char *arg, struct sender_command_data *scd)
+{
+ char *a = para_strdup(arg), *p = strchr(a, '/');
+ int ret = 0;
+
+ /* default fec parameters */
+ scd->max_slice_bytes = 0;
+ scd->data_slices_per_group = 14;
+ scd->slices_per_group = 16;
+
+ if (p) {
+ *p = '\0';
+ ret = parse_fec_parms(p + 1, scd);
+ if (ret < 0)
+ goto out;
+ }
+ if (!parse_url(a, scd->host, sizeof(scd->host), &scd->port))
+ ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+out:
+ free(a);
+ return ret;
+}