Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
pistache
Commits
88d8c865
Unverified
Commit
88d8c865
authored
Dec 28, 2018
by
Dennis Jenkins
Committed by
GitHub
Dec 28, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #388 from hydratim/IPv6
IPv6 Bug Fix
parents
6124c84c
a3537f57
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
79 additions
and
9 deletions
+79
-9
include/pistache/listener.h
include/pistache/listener.h
+2
-0
include/pistache/net.h
include/pistache/net.h
+4
-1
src/common/net.cc
src/common/net.cc
+15
-2
src/server/listener.cc
src/server/listener.cc
+25
-0
tests/listener_test.cc
tests/listener_test.cc
+19
-0
tests/net_test.cc
tests/net_test.cc
+14
-6
No files found.
include/pistache/listener.h
View file @
88d8c865
...
...
@@ -48,6 +48,8 @@ public:
Flags
<
Options
>
options
=
Options
::
None
,
int
backlog
=
Const
::
MaxBacklog
);
void
setHandler
(
const
std
::
shared_ptr
<
Handler
>&
handler
);
static
bool
systemSupportsIpv6
();
void
bind
();
void
bind
(
const
Address
&
address
);
...
...
include/pistache/net.h
View file @
88d8c865
...
...
@@ -52,6 +52,7 @@ public:
Ipv4
(
uint8_t
a
,
uint8_t
b
,
uint8_t
c
,
uint8_t
d
);
static
Ipv4
any
();
static
Ipv4
loopback
();
std
::
string
toString
()
const
;
void
toNetwork
(
in_addr_t
*
)
const
;
...
...
@@ -65,8 +66,10 @@ private:
class
Ipv6
{
public:
Ipv6
(
uint16_t
a
,
uint16_t
b
,
uint16_t
c
,
uint16_t
d
,
uint16_t
e
,
uint16_t
f
,
uint16_t
g
,
uint16_t
h
);
static
Ipv6
any
();
static
Ipv6
loopback
();
std
::
string
toString
()
const
;
void
toNetwork
(
in6_addr
*
)
const
;
...
...
src/common/net.cc
View file @
88d8c865
...
...
@@ -50,6 +50,12 @@ Ipv4::any() {
return
Ipv4
(
0
,
0
,
0
,
0
);
}
Ipv4
Ipv4
::
loopback
()
{
return
Ipv4
(
127
,
0
,
0
,
1
);
}
std
::
string
Ipv4
::
toString
()
const
{
...
...
@@ -86,6 +92,11 @@ Ipv6::any() {
return
Ipv6
(
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
}
Ipv6
Ipv6
::
loopback
()
{
return
Ipv6
(
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
);
}
std
::
string
Ipv6
::
toString
()
const
{
...
...
@@ -97,7 +108,7 @@ Ipv6::toString() const {
inet_ntop
(
AF_INET6
,
&
addr
,
buff6
,
INET6_ADDRSTRLEN
);
return
std
::
string
(
"["
)
+
std
::
string
(
buff6
)
+
std
::
string
(
"]"
);
return
std
::
string
(
buff6
);
}
void
Ipv6
::
toNetwork
(
in6_addr
*
addr6
)
const
{
...
...
@@ -196,7 +207,8 @@ Address::init(const std::string& addr) {
unsigned
long
s_pos
=
addr
.
find
(
'['
);
if
(
pos
!=
std
::
string
::
npos
&&
s_pos
!=
std
::
string
::
npos
)
{
//IPv6 address
host_
=
addr
.
substr
(
s_pos
,
pos
+
1
);
host_
=
addr
.
substr
(
s_pos
+
1
,
pos
-
1
);
family_
=
AF_INET6
;
try
{
in6_addr
addr6
;
char
buff6
[
INET6_ADDRSTRLEN
+
1
];
...
...
@@ -212,6 +224,7 @@ Address::init(const std::string& addr) {
if
(
pos
==
std
::
string
::
npos
)
throw
std
::
invalid_argument
(
"Invalid address"
);
host_
=
addr
.
substr
(
0
,
pos
);
family_
=
AF_INET
;
if
(
host_
==
"*"
)
{
host_
=
"0.0.0.0"
;
}
...
...
src/server/listener.cc
View file @
88d8c865
...
...
@@ -14,6 +14,8 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
...
...
@@ -145,6 +147,29 @@ Listener::pinWorker(size_t worker, const CpuSet& set)
#endif
}
bool
Listener
::
systemSupportsIpv6
(){
struct
ifaddrs
*
ifaddr
,
*
ifa
;
int
family
,
n
;
bool
supportsIpv6
=
false
;
if
(
getifaddrs
(
&
ifaddr
)
==
-
1
)
{
throw
std
::
runtime_error
(
"Call to getifaddrs() failed"
);
}
for
(
ifa
=
ifaddr
,
n
=
0
;
ifa
!=
NULL
;
ifa
=
ifa
->
ifa_next
,
n
++
)
{
if
(
ifa
->
ifa_addr
==
NULL
)
continue
;
family
=
ifa
->
ifa_addr
->
sa_family
;
if
(
family
==
AF_INET6
)
{
supportsIpv6
=
true
;
continue
;
}
}
freeifaddrs
(
ifaddr
);
return
supportsIpv6
;
}
void
Listener
::
bind
()
{
bind
(
addr_
);
...
...
tests/listener_test.cc
View file @
88d8c865
...
...
@@ -123,6 +123,7 @@ TEST(listener_test, listener_bind_port_free) {
ASSERT_TRUE
(
true
);
}
// Listener should not crash if an additional member is added to the listener class. This test
// is there to prevent regression for PR 303
TEST
(
listener_test
,
listener_uses_default
)
{
...
...
@@ -180,6 +181,7 @@ TEST(listener_test, listener_bind_port_not_free_throw_runtime) {
}
}
// Listener should be able to bind port 0 directly to get an ephemeral port.
TEST
(
listener_test
,
listener_bind_ephemeral_port
)
{
Pistache
::
Port
port
(
0
);
...
...
@@ -192,3 +194,20 @@ TEST(listener_test, listener_bind_ephemeral_port) {
Pistache
::
Port
bound_port
=
listener
.
getPort
();
ASSERT_TRUE
(
bound_port
>
(
uint16_t
)
0
);
}
TEST
(
listener_test
,
listener_bind_ephemeral_v6_port
)
{
Pistache
::
Port
port
(
0
);
Pistache
::
Address
address
(
Pistache
::
Ipv6
::
any
(),
port
);
Pistache
::
Tcp
::
Listener
listener
;
if
(
not
listener
.
systemSupportsIpv6
())
{
Pistache
::
Flags
<
Pistache
::
Tcp
::
Options
>
options
;
listener
.
setHandler
(
Pistache
::
Http
::
make_handler
<
DummyHandler
>
());
listener
.
bind
(
address
);
Pistache
::
Port
bound_port
=
listener
.
getPort
();
ASSERT_TRUE
(
bound_port
>
(
uint16_t
)
0
);
}
ASSERT_TRUE
(
true
);
}
tests/net_test.cc
View file @
88d8c865
...
...
@@ -50,29 +50,37 @@ TEST(net_test, address_creation)
ASSERT_EQ
(
address5
.
port
(),
8080
);
Address
address6
(
"[::1]:8080"
);
ASSERT_EQ
(
address6
.
host
(),
"
[::1]
"
);
ASSERT_EQ
(
address6
.
host
(),
"
::1
"
);
ASSERT_EQ
(
address6
.
port
(),
8080
);
std
::
string
addr2
=
"[::1]"
;
Address
address7
(
addr2
,
Port
(
8080
));
ASSERT_EQ
(
address7
.
host
(),
"
[::1]
"
);
ASSERT_EQ
(
address7
.
host
(),
"
::1
"
);
ASSERT_EQ
(
address7
.
port
(),
8080
);
Address
address8
(
Ipv6
(
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
),
Port
(
8080
));
ASSERT_EQ
(
address8
.
host
(),
"
[::1]
"
);
ASSERT_EQ
(
address8
.
host
(),
"
::1
"
);
ASSERT_EQ
(
address8
.
port
(),
8080
);
Address
address9
(
Ipv6
::
any
(),
Port
(
8080
));
ASSERT_EQ
(
address9
.
host
(),
"
[::]
"
);
ASSERT_EQ
(
address9
.
host
(),
"
::
"
);
ASSERT_EQ
(
address9
.
port
(),
8080
);
Address
address10
(
"[::]:8080"
);
ASSERT_EQ
(
address10
.
host
(),
"
[::]
"
);
ASSERT_EQ
(
address10
.
host
(),
"
::
"
);
ASSERT_EQ
(
address10
.
port
(),
8080
);
Address
address11
(
"[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]:8080"
);
ASSERT_EQ
(
address11
.
host
(),
"
[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]
"
);
ASSERT_EQ
(
address11
.
host
(),
"
2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455
"
);
ASSERT_EQ
(
address11
.
port
(),
8080
);
Address
address12
(
Ipv4
::
loopback
(),
Port
(
8080
));
ASSERT_EQ
(
address12
.
host
(),
"127.0.0.1"
);
ASSERT_EQ
(
address12
.
port
(),
8080
);
Address
address13
(
Ipv6
::
loopback
(),
Port
(
8080
));
ASSERT_EQ
(
address13
.
host
(),
"::1"
);
ASSERT_EQ
(
address13
.
port
(),
8080
);
}
TEST
(
net_test
,
invalid_address
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment