X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=config.cpp;h=f17302a4e92c4b136a2d1c182d8aef4ff313c8dd;hp=c5547bda4f5d62ef155ffa4cf1381819658c90f4;hb=845934ca50eee40884e8cc85ea81eb310efa5ca3;hpb=8f44468bfe4a1d1607b0ab7044c3071605ae1fa7 diff --git a/config.cpp b/config.cpp index c5547bd..f17302a 100644 --- a/config.cpp +++ b/config.cpp @@ -1,8 +1,11 @@ +#include #include #include +#include #include #include #include +#include #include #include #include @@ -189,12 +192,12 @@ bool parse_stream(const ConfigLine &line, Config *config) } StreamConfig stream; - stream.stream_id = line.arguments[0]; + stream.url = line.arguments[0]; map::const_iterator src_it = line.parameters.find("src"); if (src_it == line.parameters.end()) { log(WARNING, "stream '%s' has no src= attribute, clients will not get any data.", - stream.stream_id.c_str()); + stream.url.c_str()); } else { stream.src = src_it->second; // TODO: Verify that the URL is parseable? @@ -235,6 +238,87 @@ bool parse_stream(const ConfigLine &line, Config *config) return true; } +bool parse_udpstream(const ConfigLine &line, Config *config) +{ + if (line.arguments.size() != 1) { + log(ERROR, "'udpstream' takes exactly one argument"); + return false; + } + + UDPStreamConfig udpstream; + + string hostport = line.arguments[0]; + + // See if the argument if on the type [ipv6addr]:port. + if (!hostport.empty() && hostport[0] == '[') { + size_t split = hostport.find("]:"); + if (split == string::npos) { + log(ERROR, "udpstream destination '%s' is malformed; must be either [ipv6addr]:port or ipv4addr:port"); + return false; + } + + string host(hostport.begin() + 1, hostport.begin() + split); + string port = hostport.substr(split + 2); + + udpstream.dst.sin6_family = AF_INET6; + if (inet_pton(AF_INET6, host.c_str(), &udpstream.dst.sin6_addr) != 1) { + log(ERROR, "udpstream destination host '%s' is not a valid IPv6 address"); + return false; + } + + udpstream.dst.sin6_port = htons(atoi(port.c_str())); // TODO: Verify validity. + } else { + // OK, then it must be ipv4addr:port. + size_t split = hostport.find(":"); + if (split == string::npos) { + log(ERROR, "udpstream destination '%s' is malformed; must be either [ipv6addr]:port or ipv4addr:port"); + return false; + } + + string host(hostport.begin(), hostport.begin() + split); + string port = hostport.substr(split + 1); + + // Parse to an IPv4 address, then construct a mapped-v4 address from that. + in_addr addr4; + + if (inet_pton(AF_INET, host.c_str(), &addr4) != 1) { + log(ERROR, "udpstream destination host '%s' is not a valid IPv4 address"); + return false; + } + + udpstream.dst.sin6_family = AF_INET6; + udpstream.dst.sin6_addr.s6_addr32[0] = 0; + udpstream.dst.sin6_addr.s6_addr32[1] = 0; + udpstream.dst.sin6_addr.s6_addr32[2] = htonl(0xffff); + udpstream.dst.sin6_addr.s6_addr32[3] = addr4.s_addr; + udpstream.dst.sin6_port = htons(atoi(port.c_str())); // TODO: Verify validity. + } + + map::const_iterator src_it = line.parameters.find("src"); + if (src_it == line.parameters.end()) { + // This is pretty meaningless, but OK, consistency is good. + log(WARNING, "udpstream to %s has no src= attribute, clients will not get any data.", + hostport.c_str()); + } else { + udpstream.src = src_it->second; + // TODO: Verify that the URL is parseable? + } + + // Parse marks, if so desired. + map::const_iterator mark_parm_it = line.parameters.find("mark"); + if (mark_parm_it == line.parameters.end()) { + udpstream.mark_pool = -1; + } else { + int from, to; + if (!parse_mark_pool(mark_parm_it->second, &from, &to)) { + return false; + } + udpstream.mark_pool = allocate_mark_pool(from, to, config); + } + + config->udpstreams.push_back(udpstream); + return true; +} bool parse_error_log(const ConfigLine &line, Config *config) { if (line.arguments.size() != 0) { @@ -317,6 +401,10 @@ bool parse_config(const string &filename, Config *config) if (!parse_stream(line, config)) { return false; } + } else if (line.keyword == "udpstream") { + if (!parse_udpstream(line, config)) { + return false; + } } else if (line.keyword == "error_log") { if (!parse_error_log(line, config)) { return false;