1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

For #988, refine code.

This commit is contained in:
winlin 2017-10-14 12:09:53 +08:00
parent 823dc2df21
commit 922a8f3a5c
11 changed files with 104 additions and 122 deletions

View file

@ -34,6 +34,7 @@
#include <netdb.h> #include <netdb.h>
using namespace std; using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_app_server.hpp> #include <srs_app_server.hpp>
@ -112,31 +113,31 @@ srs_error_t SrsUdpListener::listen()
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
char port_string[8]; char sport[8];
snprintf(port_string, sizeof(port_string), "%d", port); snprintf(sport, sizeof(sport), "%d", port);
addrinfo hints; addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST; hints.ai_flags = AI_NUMERICHOST;
addrinfo* result = NULL;
if(getaddrinfo(ip.c_str(), port_string, (const addrinfo*)&hints, &result) != 0) { addrinfo* r = NULL;
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "bad address"); SrsAutoFree(addrinfo, r);
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r) != 0) {
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "get address info");
} }
if ((_fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol)) == -1) { if ((_fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) {
freeaddrinfo(result); return srs_error_new(ERROR_SOCKET_CREATE, "create socket. ip=%s, port=%d", ip.c_str(), port);
return srs_error_new(ERROR_SOCKET_CREATE, "create linux socket error. ip=%s, port=%d", ip.c_str(), port);
} }
srs_fd_close_exec(_fd); srs_fd_close_exec(_fd);
srs_socket_reuse_addr(_fd); srs_socket_reuse_addr(_fd);
if (bind(_fd, result->ai_addr, result->ai_addrlen) == -1) { if (bind(_fd, r->ai_addr, r->ai_addrlen) == -1) {
freeaddrinfo(result); return srs_error_new(ERROR_SOCKET_BIND, "bind socket. ep=%s:%d", ip.c_str(), port);;
return srs_error_new(ERROR_SOCKET_BIND, "bind socket error. ep=%s:%d", ip.c_str(), port);;
} }
freeaddrinfo(result);
if ((_stfd = srs_netfd_open_socket(_fd)) == NULL){ if ((_stfd = srs_netfd_open_socket(_fd)) == NULL){
return srs_error_new(ERROR_ST_OPEN_SOCKET, "st open socket"); return srs_error_new(ERROR_ST_OPEN_SOCKET, "st open socket");
@ -208,31 +209,31 @@ srs_error_t SrsTcpListener::listen()
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
char port_string[8]; char sport[8];
snprintf(port_string, sizeof(port_string), "%d", port); snprintf(sport, sizeof(sport), "%d", port);
addrinfo hints; addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST; hints.ai_flags = AI_NUMERICHOST;
addrinfo* result = NULL;
if(getaddrinfo(ip.c_str(), port_string, (const addrinfo*)&hints, &result) != 0) { addrinfo* r = NULL;
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "bad address"); SrsAutoFree(addrinfo, r);
if(getaddrinfo(ip.c_str(), sport, (const addrinfo*)&hints, &r) != 0) {
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "get address info");
} }
if ((_fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol)) == -1) { if ((_fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) {
freeaddrinfo(result); return srs_error_new(ERROR_SOCKET_CREATE, "create socket. ip=%s, port=%d", ip.c_str(), port);
return srs_error_new(ERROR_SOCKET_CREATE, "create linux socket error. ip=%s, port=%d", ip.c_str(), port);
} }
srs_fd_close_exec(_fd); srs_fd_close_exec(_fd);
srs_socket_reuse_addr(_fd); srs_socket_reuse_addr(_fd);
if (bind(_fd, result->ai_addr, result->ai_addrlen) == -1) { if (bind(_fd, r->ai_addr, r->ai_addrlen) == -1) {
freeaddrinfo(result); return srs_error_new(ERROR_SOCKET_BIND, "bind socket. ep=%s:%d", ip.c_str(), port);;
return srs_error_new(ERROR_SOCKET_BIND, "bind socket error. ep=%s:%d", ip.c_str(), port);;
} }
freeaddrinfo(result);
if (::listen(_fd, SERVER_LISTEN_BACKLOG) == -1) { if (::listen(_fd, SERVER_LISTEN_BACKLOG) == -1) {
return srs_error_new(ERROR_SOCKET_LISTEN, "listen socket"); return srs_error_new(ERROR_SOCKET_LISTEN, "listen socket");

View file

@ -54,7 +54,7 @@ SrsRtpConn::SrsRtpConn(SrsRtspConn* r, int p, int sid)
_port = p; _port = p;
stream_id = sid; stream_id = sid;
// TODO: support listen at <[ip:]port> // TODO: support listen at <[ip:]port>
listener = new SrsUdpListener(this, (srs_check_ipv6() ? "::" : "0.0.0.0"), p); listener = new SrsUdpListener(this, srs_any_address4listener(), p);
cache = new SrsRtpPacket(); cache = new SrsRtpPacket();
pprint = SrsPithyPrint::create_caster(); pprint = SrsPithyPrint::create_caster();
} }

View file

@ -1137,7 +1137,7 @@ srs_error_t SrsServer::listen_stream_caster()
} }
// TODO: support listen at <[ip:]port> // TODO: support listen at <[ip:]port>
if ((err = listener->listen( (srs_check_ipv6() ? "::" : "0.0.0.0"), port)) != srs_success) { if ((err = listener->listen(srs_any_address4listener(), port)) != srs_success) {
return srs_error_wrap(err, "listen at %d", port); return srs_error_wrap(err, "listen at %d", port);
} }
} }

View file

@ -1104,16 +1104,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
} }
} }
int srs_check_ipv6()
{
int sd = socket(AF_INET6, SOCK_DGRAM, 0);
if(sd >= 0) {
close(sd);
return 1;
}
return 0;
}
string srs_get_local_ip(int fd) string srs_get_local_ip(int fd)
{ {
// discovery client information // discovery client information
@ -1122,19 +1112,16 @@ string srs_get_local_ip(int fd)
if (getsockname(fd, (sockaddr*)&addr, &addrlen) == -1) { if (getsockname(fd, (sockaddr*)&addr, &addrlen) == -1) {
return ""; return "";
} }
srs_verbose("get local ip success.");
char address_string[64]; char saddr[64];
const int success = getnameinfo((const sockaddr*)&addr, addrlen, char* h = (char*)saddr;
(char*)&address_string, sizeof(address_string), socklen_t nbh = (socklen_t)sizeof(saddr);
NULL, 0, const int r0 = getnameinfo((const sockaddr*)&addr, addrlen, h, nbh,NULL, 0, NI_NUMERICHOST);
NI_NUMERICHOST); if(r0 != 0) {
if(success != 0) {
return ""; return "";
} }
srs_verbose("get local ip of client ip=%s, fd=%d", address_string, fd); return std::string(saddr);
return std::string(address_string);
} }
int srs_get_local_port(int fd) int srs_get_local_port(int fd)
@ -1145,7 +1132,6 @@ int srs_get_local_port(int fd)
if (getsockname(fd, (sockaddr*)&addr, &addrlen) == -1) { if (getsockname(fd, (sockaddr*)&addr, &addrlen) == -1) {
return 0; return 0;
} }
srs_verbose("get local ip success.");
int port = 0; int port = 0;
switch(addr.ss_family) { switch(addr.ss_family) {
@ -1157,7 +1143,6 @@ int srs_get_local_port(int fd)
break; break;
} }
srs_verbose("get local port of client port=%s, fd=%d", port, fd);
return port; return port;
} }
@ -1169,19 +1154,16 @@ string srs_get_peer_ip(int fd)
if (getsockname(fd, (sockaddr*)&addr, &addrlen) == -1) { if (getsockname(fd, (sockaddr*)&addr, &addrlen) == -1) {
return ""; return "";
} }
srs_verbose("get peer ip success.");
char address_string[64]; char saddr[64];
const int success = getnameinfo((const sockaddr*)&addr, addrlen, char* h = (char*)saddr;
(char*)&address_string, sizeof(address_string), socklen_t nbh = (socklen_t)sizeof(saddr);
NULL, 0, const int r0 = getnameinfo((const sockaddr*)&addr, addrlen, h, nbh, NULL, 0, NI_NUMERICHOST);
NI_NUMERICHOST); if(r0 != 0) {
if(success != 0) {
return ""; return "";
} }
srs_verbose("get peer ip of client ip=%s, fd=%d", address_string, fd); return std::string(saddr);
return std::string(address_string);
} }
bool srs_is_digit_number(const string& str) bool srs_is_digit_number(const string& str)

View file

@ -643,9 +643,6 @@ extern SrsNetworkRtmpServer* srs_get_network_rtmp_server();
// the deamon st-thread will update it. // the deamon st-thread will update it.
extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps); extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps);
// check for IPv6 support
extern int srs_check_ipv6();
// get local or peer ip. // get local or peer ip.
// where local ip is the server ip which client connected. // where local ip is the server ip which client connected.
extern std::string srs_get_local_ip(int fd); extern std::string srs_get_local_ip(int fd);

View file

@ -39,6 +39,7 @@
#include <vector> #include <vector>
using namespace std; using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_kernel_buffer.hpp> #include <srs_kernel_buffer.hpp>
@ -159,21 +160,22 @@ string srs_dns_resolve(string host, int& family)
addrinfo hints; addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = family; hints.ai_family = family;
addrinfo* result = NULL;
if(getaddrinfo(host.c_str(), NULL, NULL, &result) != 0) { addrinfo* r = NULL;
SrsAutoFree(addrinfo, r);
if(getaddrinfo(host.c_str(), NULL, NULL, &r) != 0) {
return ""; return "";
} }
char address_string[64]; char saddr[64];
const int success = getnameinfo(result->ai_addr, result->ai_addrlen, char* h = (char*)saddr;
(char*)&address_string, sizeof(address_string), socklen_t nbh = sizeof(saddr);
NULL, 0, const int r0 = getnameinfo(r->ai_addr, r->ai_addrlen, h, nbh, NULL, 0, NI_NUMERICHOST);
NI_NUMERICHOST);
freeaddrinfo(result);
if(success) { if(r0) {
family = result->ai_family; family = r->ai_family;
return string(address_string); return string(saddr);
} }
return ""; return "";
} }
@ -188,8 +190,7 @@ void srs_parse_hostport(const string& hostport, string& host, int& port)
(hostport[pos - 1] == ']')) { (hostport[pos - 1] == ']')) {
// Handle IPv6 in RFC 2732 format, e.g. [3ffe:dead:beef::1]:1935 // Handle IPv6 in RFC 2732 format, e.g. [3ffe:dead:beef::1]:1935
host = hostport.substr(1, pos - 2); host = hostport.substr(1, pos - 2);
} } else {
else {
// Handle IP address // Handle IP address
host = hostport.substr(0, pos); host = hostport.substr(0, pos);
} }
@ -199,34 +200,37 @@ void srs_parse_hostport(const string& hostport, string& host, int& port)
} }
} }
static int check_ipv6() string srs_any_address4listener()
{ {
int sd = socket(AF_INET6, SOCK_DGRAM, 0); int fd = socket(AF_INET6, SOCK_DGRAM, 0);
if(sd >= 0) {
close(sd); // socket()
return 1; // A -1 is returned if an error occurs, otherwise the return value is a
// descriptor referencing the socket.
if(fd != -1) {
close(fd);
return "::";
} }
return 0;
return "0.0.0.0";
} }
void srs_parse_endpoint(string hostport, string& ip, int& port) void srs_parse_endpoint(string hostport, string& ip, int& port)
{ {
const size_t pos = hostport.rfind(":"); // Look for ":" from the end, to work with IPv6. const size_t pos = hostport.rfind(":"); // Look for ":" from the end, to work with IPv6.
if (pos != std::string::npos) { if (pos != std::string::npos) {
if ((pos >= 1) && if ((pos >= 1) && (hostport[0] == '[') && (hostport[pos - 1] == ']')) {
(hostport[0] == '[') &&
(hostport[pos - 1] == ']')) {
// Handle IPv6 in RFC 2732 format, e.g. [3ffe:dead:beef::1]:1935 // Handle IPv6 in RFC 2732 format, e.g. [3ffe:dead:beef::1]:1935
ip = hostport.substr(1, pos - 2); ip = hostport.substr(1, pos - 2);
} } else {
else {
// Handle IP address // Handle IP address
ip = hostport.substr(0, pos); ip = hostport.substr(0, pos);
} }
const string sport = hostport.substr(pos + 1); const string sport = hostport.substr(pos + 1);
port = ::atoi(sport.c_str()); port = ::atoi(sport.c_str());
} else { } else {
ip = check_ipv6() ? "::" : "0.0.0.0"; ip = srs_any_address4listener();
port = ::atoi(hostport.c_str()); port = ::atoi(hostport.c_str());
} }
} }

View file

@ -46,6 +46,10 @@ extern int64_t srs_get_system_startup_time_ms();
// the deamon st-thread will update it. // the deamon st-thread will update it.
extern int64_t srs_update_system_time_ms(); extern int64_t srs_update_system_time_ms();
// the any address for listener,
// it's "0.0.0.0" for ipv4, and "::" for ipv6.
extern std::string srs_any_address4listener();
// dns resolve utility, return the resolved ip address. // dns resolve utility, return the resolved ip address.
extern std::string srs_dns_resolve(std::string host, int& family); extern std::string srs_dns_resolve(std::string host, int& family);

View file

@ -67,6 +67,7 @@
#include <stdio.h> #include <stdio.h>
#include <netdb.h> #include <netdb.h>
#include <srs_core_autofree.hpp>
#include <srs_kernel_utility.hpp> #include <srs_kernel_utility.hpp>
#include <srs_kernel_consts.hpp> #include <srs_kernel_consts.hpp>
@ -125,23 +126,23 @@ int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port)
{ {
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
char port_string[8]; char sport[8];
snprintf(port_string, sizeof(port_string), "%d", port); snprintf(sport, sizeof(sport), "%d", port);
addrinfo hints; addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = skt->family; hints.ai_family = skt->family;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICHOST; hints.ai_flags = AI_NUMERICHOST;
addrinfo* result = NULL;
if(getaddrinfo(server_ip, port_string, (const addrinfo*)&hints, &result) == 0) { addrinfo* r = NULL;
if(::connect(skt->fd, result->ai_addr, result->ai_addrlen) < 0){ SrsAutoFree(addrinfo, r);
freeaddrinfo(result); if(getaddrinfo(server_ip, sport, (const addrinfo*)&hints, &r) == 0) {
if(::connect(skt->fd, r->ai_addr, r->ai_addrlen) < 0){
return ERROR_SOCKET_CONNECT; return ERROR_SOCKET_CONNECT;
} }
} }
freeaddrinfo(result);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread)

View file

@ -342,9 +342,9 @@ const char* inet_ntop(int af, const void *src, char *dst, socklen_t size)
{ {
switch (af) { switch (af) {
case AF_INET: case AF_INET:
return (inet_ntop4( (unsigned char*)src, (char*)dst, size)); return (inet_ntop4((unsigned char*)src, (char*)dst, size));
case AF_INET6: case AF_INET6:
return (char*)(inet_ntop6( (unsigned char*)src, (char*)dst, size)); return (char*)(inet_ntop6((unsigned char*)src, (char*)dst, size));
default: default:
return (NULL); return (NULL);
} }

View file

@ -29,6 +29,7 @@
#include <netdb.h> #include <netdb.h>
using namespace std; using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
#include <srs_service_utility.hpp> #include <srs_service_utility.hpp>
@ -113,40 +114,36 @@ srs_error_t srs_socket_connect(string server, int port, int64_t tm, srs_netfd_t*
*pstfd = NULL; *pstfd = NULL;
srs_netfd_t stfd = NULL; srs_netfd_t stfd = NULL;
char port_string[8]; char sport[8];
snprintf(port_string, sizeof(port_string), "%d", port); snprintf(sport, sizeof(sport), "%d", port);
addrinfo hints; addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
addrinfo* result = NULL;
if(getaddrinfo(server.c_str(), port_string, (const addrinfo*)&hints, &result) != 0) { addrinfo* r = NULL;
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "dns resolve server error"); SrsAutoFree(addrinfo, r);
if(getaddrinfo(server.c_str(), sport, (const addrinfo*)&hints, &r) != 0) {
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "get address info");
} }
int sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol); int sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
if(sock == -1){ if(sock == -1){
freeaddrinfo(result);
return srs_error_new(ERROR_SOCKET_CREATE, "create socket"); return srs_error_new(ERROR_SOCKET_CREATE, "create socket");
} }
srs_assert(!stfd); srs_assert(!stfd);
stfd = st_netfd_open_socket(sock); stfd = st_netfd_open_socket(sock);
if(stfd == NULL){ if(stfd == NULL){
srs_close_stfd(stfd);
freeaddrinfo(result);
return srs_error_new(ERROR_ST_OPEN_SOCKET, "open socket"); return srs_error_new(ERROR_ST_OPEN_SOCKET, "open socket");
} }
if (st_connect((st_netfd_t)stfd, result->ai_addr, result->ai_addrlen, timeout) == -1){ if (st_connect((st_netfd_t)stfd, r->ai_addr, r->ai_addrlen, timeout) == -1){
srs_close_stfd(stfd); srs_close_stfd(stfd);
freeaddrinfo(result);
return srs_error_new(ERROR_ST_CONNECT, "connect to %s:%d", server.c_str(), port); return srs_error_new(ERROR_ST_CONNECT, "connect to %s:%d", server.c_str(), port);
} }
srs_info("connect ok. server=%s, port=%d", server.c_str(), port);
freeaddrinfo(result);
*pstfd = stfd; *pstfd = stfd;
return srs_success; return srs_success;
} }

View file

@ -87,8 +87,7 @@ bool srs_net_device_is_internet(const sockaddr* addr)
if (addr_h >= 0xc0a80000 && addr_h <= 0xc0a8ffff) { if (addr_h >= 0xc0a80000 && addr_h <= 0xc0a8ffff) {
return false; return false;
} }
} } else if(addr->sa_family == AF_INET6) {
else if(addr->sa_family == AF_INET6) {
const sockaddr_in6* a6 = (const sockaddr_in6*)addr; const sockaddr_in6* a6 = (const sockaddr_in6*)addr;
if ((IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr)) || if ((IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr)) ||
(IN6_IS_ADDR_SITELOCAL(&a6->sin6_addr))) { (IN6_IS_ADDR_SITELOCAL(&a6->sin6_addr))) {
@ -128,20 +127,17 @@ void retrieve_local_ips()
// ignore the tun0 network device, // ignore the tun0 network device,
// which addr is NULL. // which addr is NULL.
// @see: https://github.com/ossrs/srs/issues/141 // @see: https://github.com/ossrs/srs/issues/141
if ( (cur->ifa_addr) && if ((cur->ifa_addr) && ((cur->ifa_addr->sa_family == AF_INET) || (cur->ifa_addr->sa_family == AF_INET6))) {
( (cur->ifa_addr->sa_family == AF_INET) || char saddr[64];
(cur->ifa_addr->sa_family == AF_INET6) ) ) { char* h = (char*)saddr;
char address_string[64]; socklen_t nbh = (socklen_t)sizeof(saddr);
const int success = getnameinfo(cur->ifa_addr, sizeof(sockaddr_storage), const int r0 = getnameinfo(cur->ifa_addr, sizeof(sockaddr_storage), h, nbh, NULL, 0, NI_NUMERICHOST);
(char*)&address_string, sizeof(address_string), if(r0 != 0) {
NULL, 0, srs_warn("convert local ip failed: %s", gai_strerror(r0));
NI_NUMERICHOST);
if(success != 0) {
srs_warn("convert local ip failed: %s", gai_strerror(success));
break; break;
} }
std::string ip = address_string; std::string ip = saddr;
if (ip != SRS_CONSTS_LOCALHOST) { if (ip != SRS_CONSTS_LOCALHOST) {
ss0 << ", local[" << (int)ips.size() << "] ipv4 " << ip; ss0 << ", local[" << (int)ips.size() << "] ipv4 " << ip;
ips.push_back(ip); ips.push_back(ip);