Skip to content

Commit f6773a0

Browse files
authored
Support IPv6 (#15)
1 parent c0a2d32 commit f6773a0

File tree

2 files changed

+63
-19
lines changed

2 files changed

+63
-19
lines changed

c_src/ex_libsrt/client/client.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "client.h"
22

3+
#include <cstring>
34
#include <exception>
45
#include <utility>
56
#include <chrono>
@@ -20,23 +21,43 @@ void Client::Run(const std::string& address,
2021
const std::string& password,
2122
int latency_ms) {
2223
this->password = password;
23-
24+
25+
struct sockaddr_storage ss;
26+
socklen_t ss_len;
27+
int af;
28+
memset(&ss, 0, sizeof(ss));
29+
30+
struct sockaddr_in6 *sa6 = reinterpret_cast<struct sockaddr_in6*>(&ss);
31+
struct sockaddr_in *sa4 = reinterpret_cast<struct sockaddr_in*>(&ss);
32+
33+
if (inet_pton(AF_INET6, address.c_str(), &sa6->sin6_addr) == 1) {
34+
sa6->sin6_family = AF_INET6;
35+
sa6->sin6_port = htons(port);
36+
ss_len = sizeof(struct sockaddr_in6);
37+
af = AF_INET6;
38+
} else if (inet_pton(AF_INET, address.c_str(), &sa4->sin_addr) == 1) {
39+
sa4->sin_family = AF_INET;
40+
sa4->sin_port = htons(port);
41+
ss_len = sizeof(struct sockaddr_in);
42+
af = AF_INET;
43+
} else {
44+
throw std::runtime_error("Failed to parse server address: " + address);
45+
}
46+
2447
srt_sock = srt_create_socket();
2548
if (srt_sock == SRT_ERROR) {
2649
throw std::runtime_error(std::string(srt_getlasterror_str()));
2750
}
2851

29-
struct sockaddr_in sa;
30-
sa.sin_family = AF_INET;
31-
sa.sin_port = htons(port);
32-
33-
if (inet_pton(AF_INET, address.c_str(), &sa.sin_addr) != 1) {
34-
throw std::runtime_error("Failed to parse server address");
35-
}
36-
3752
int yes = 1;
3853
int no = 0;
3954

55+
if (af == AF_INET6) {
56+
if (srt_setsockflag(srt_sock, SRTO_IPV6ONLY, &yes, sizeof yes) == SRT_ERROR) {
57+
throw std::runtime_error(std::string(srt_getlasterror_str()));
58+
}
59+
}
60+
4061
if (srt_setsockflag(srt_sock, SRTO_SENDER, &yes, sizeof yes) == SRT_ERROR) {
4162
throw std::runtime_error(std::string(srt_getlasterror_str()));
4263
}
@@ -77,7 +98,7 @@ void Client::Run(const std::string& address,
7798
throw std::runtime_error(std::string(srt_getlasterror_str()));
7899
}
79100

80-
int result = srt_connect(srt_sock, (struct sockaddr*)&sa, sizeof sa);
101+
int result = srt_connect(srt_sock, reinterpret_cast<struct sockaddr*>(&ss), ss_len);
81102
if (result == SRT_ERROR) {
82103
auto code = srt_getrejectreason(srt_sock);
83104

c_src/ex_libsrt/server/server.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "server.h"
22

33
#include <chrono>
4+
#include <cstring>
45
#include <exception>
56
#include <string>
67
#include <vector>
@@ -12,21 +13,43 @@ void Server::Run(const std::string& address,
1213
int latency_ms) {
1314
this->password = password;
1415
this->latency_ms = latency_ms;
15-
16+
17+
struct sockaddr_storage ss;
18+
socklen_t ss_len;
19+
int af;
20+
memset(&ss, 0, sizeof(ss));
21+
22+
struct sockaddr_in6 *sa6 = reinterpret_cast<struct sockaddr_in6*>(&ss);
23+
struct sockaddr_in *sa4 = reinterpret_cast<struct sockaddr_in*>(&ss);
24+
25+
if (inet_pton(AF_INET6, address.c_str(), &sa6->sin6_addr) == 1) {
26+
sa6->sin6_family = AF_INET6;
27+
sa6->sin6_port = htons(port);
28+
ss_len = sizeof(struct sockaddr_in6);
29+
af = AF_INET6;
30+
} else if (inet_pton(AF_INET, address.c_str(), &sa4->sin_addr) == 1) {
31+
sa4->sin_family = AF_INET;
32+
sa4->sin_port = htons(port);
33+
ss_len = sizeof(struct sockaddr_in);
34+
af = AF_INET;
35+
} else {
36+
throw std::runtime_error("Failed to parse server address: " + address);
37+
}
38+
1639
srt_sock = srt_create_socket();
1740
if (srt_sock == SRT_ERROR) {
1841
throw std::runtime_error(std::string(srt_getlasterror_str()));
1942
}
2043

21-
struct sockaddr_in sa;
22-
sa.sin_family = AF_INET;
23-
sa.sin_port = htons(port);
24-
if (inet_pton(AF_INET, address.c_str(), &(sa).sin_addr) != 1) {
25-
throw std::runtime_error("Failed to parse server address");
26-
}
27-
2844
int yes = 1;
2945
int no = 0;
46+
47+
if (af == AF_INET6) {
48+
if (srt_setsockflag(srt_sock, SRTO_IPV6ONLY, &yes, sizeof yes) == SRT_ERROR) {
49+
throw std::runtime_error(std::string(srt_getlasterror_str()));
50+
}
51+
}
52+
3053
srt_setsockflag(srt_sock, SRTO_RCVSYN, &no, sizeof yes);
3154
srt_setsockflag(srt_sock, SRTO_STREAMID, &yes, sizeof yes);
3255
if (latency_ms >= 0) {
@@ -35,7 +58,7 @@ void Server::Run(const std::string& address,
3558
}
3659
}
3760

38-
srt_bind_sock = srt_bind(srt_sock, (struct sockaddr*)&(sa), sizeof sa);
61+
srt_bind_sock = srt_bind(srt_sock, reinterpret_cast<struct sockaddr*>(&ss), ss_len);
3962
if (srt_bind_sock == SRT_ERROR) {
4063
throw std::runtime_error(std::string(srt_getlasterror_str()));
4164
}

0 commit comments

Comments
 (0)