diff --git a/README.md b/README.md index 629d93211..561c0165b 100755 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ For previous versions, please read: ## V3 changes +* v3.0, 2020-01-05, For [#460][bug #460], fix ipv6 hostport parsing bug. 3.0.94 * v3.0, 2020-01-05, For [#460][bug #460], fix ipv6 intranet address filter bug. 3.0.93 * v3.0, 2020-01-05, For [#1543][bug #1543], use getpeername to retrieve client ip. 3.0.92 * v3.0, 2020-01-02, For [#1042][bug #1042], improve test coverage for config. 3.0.91 diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 2ddb51420..b4b9edbd5 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 93 +#define VERSION_REVISION 94 // The macros generated by configure script. #include diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 1d091338e..861be3610 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -188,23 +188,42 @@ string srs_dns_resolve(string host, int& family) return string(shost); } -void srs_parse_hostport(const string& hostport, string& host, int& port) +void srs_parse_hostport(string hostport, string& host, int& port) { - const size_t pos = hostport.rfind(":"); // Look for ":" from the end, to work with IPv6. - if (pos != std::string::npos) { - const string p = hostport.substr(pos + 1); - if ((pos >= 1) && - (hostport[0] == '[') && - (hostport[pos - 1] == ']')) { - // Handle IPv6 in RFC 2732 format, e.g. [3ffe:dead:beef::1]:1935 - host = hostport.substr(1, pos - 2); - } else { - // Handle IP address - host = hostport.substr(0, pos); - } - port = ::atoi(p.c_str()); - } else { + // No host or port. + if (hostport.empty()) { + return; + } + + size_t pos = string::npos; + + // Host only for ipv4. + if ((pos = hostport.rfind(":")) == string::npos) { host = hostport; + return; + } + + // For ipv4(only one colon), host:port. + if (hostport.find(":") == pos) { + host = hostport.substr(0, pos); + string p = hostport.substr(pos + 1); + if (!p.empty()) { + port = ::atoi(p.c_str()); + } + return; + } + + // Host only for ipv6. + if (hostport.at(0) != '[' || (pos = hostport.rfind("]:")) == string::npos) { + host = hostport; + return; + } + + // For ipv6, [host]:port. + host = hostport.substr(1, pos - 1); + string p = hostport.substr(pos + 2); + if (!p.empty()) { + port = ::atoi(p.c_str()); } }