X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=config.cpp;h=d47bfec0fbb72fc4fe668939805ad54d7249d861;hp=405033868f65f8c804cff3570e4e384dbf198d94;hb=adbeb2f8972672ed1059509662d006df47762228;hpb=0ff463f4df8e085ba88f8ede735f16b140a2bf8e;ds=sidebyside diff --git a/config.cpp b/config.cpp index 4050338..d47bfec 100644 --- a/config.cpp +++ b/config.cpp @@ -235,6 +235,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 +398,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;