Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
e53d0563
Commit
e53d0563
authored
Jul 28, 2013
by
Sergey Lyubka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Binding to IPv6 addresses
parent
9d75d353
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
29 deletions
+74
-29
mongoose.c
mongoose.c
+36
-25
unit_test.c
test/unit_test.c
+38
-4
No files found.
mongoose.c
View file @
e53d0563
...
...
@@ -4499,41 +4499,50 @@ static void close_all_listening_sockets(struct mg_context *ctx) {
free
(
ctx
->
listening_sockets
);
}
static
int
is_valid_port
(
unsigned
int
port
)
{
return
port
>
0
&&
port
<
0xffff
;
}
// Valid listening port specification is: [ip_address:]port[s]
// Examples: 80, 443s, 127.0.0.1:3128, 1.2.3.4:8080s
// TODO(lsm): add parsing of the IPv6 address
static
int
parse_port_string
(
const
struct
vec
*
vec
,
struct
socket
*
so
)
{
int
a
,
b
,
c
,
d
,
port
,
len
;
unsigned
int
a
,
b
,
c
,
d
,
ch
,
len
,
port
;
#if defined(USE_IPV6)
char
buf
[
100
];
#endif
// MacOS needs that. If we do not zero it, subsequent bind() will fail.
// Also, all-zeroes in the socket address means binding to all addresses
// for both IPv4 and IPv6 (INADDR_ANY and IN6ADDR_ANY_INIT).
memset
(
so
,
0
,
sizeof
(
*
so
));
so
->
lsa
.
sin
.
sin_family
=
AF_INET
;
if
(
sscanf
(
vec
->
ptr
,
"%
d.%d.%d.%d:%d
%n"
,
&
a
,
&
b
,
&
c
,
&
d
,
&
port
,
&
len
)
==
5
)
{
// Bind to a specific IPv4 address
if
(
sscanf
(
vec
->
ptr
,
"%
u.%u.%u.%u:%u
%n"
,
&
a
,
&
b
,
&
c
,
&
d
,
&
port
,
&
len
)
==
5
)
{
// Bind to a specific IPv4 address
, e.g. 192.168.1.5:8080
so
->
lsa
.
sin
.
sin_addr
.
s_addr
=
htonl
((
a
<<
24
)
|
(
b
<<
16
)
|
(
c
<<
8
)
|
d
);
}
else
if
(
sscanf
(
vec
->
ptr
,
"%d%n"
,
&
port
,
&
len
)
!=
1
||
len
<=
0
||
len
>
(
int
)
vec
->
len
||
port
<
1
||
port
>
65535
||
(
vec
->
ptr
[
len
]
&&
vec
->
ptr
[
len
]
!=
's'
&&
vec
->
ptr
[
len
]
!=
'r'
&&
vec
->
ptr
[
len
]
!=
','
))
{
return
0
;
}
so
->
is_ssl
=
vec
->
ptr
[
len
]
==
's'
;
so
->
ssl_redir
=
vec
->
ptr
[
len
]
==
'r'
;
so
->
lsa
.
sin
.
sin_port
=
htons
((
uint16_t
)
port
);
#if defined(USE_IPV6)
so
->
lsa
.
sin6
.
sin6_family
=
AF_INET6
;
so
->
lsa
.
sin6
.
sin6_port
=
htons
((
uint16_t
)
port
);
#else
so
->
lsa
.
sin
.
sin_family
=
AF_INET
;
so
->
lsa
.
sin
.
sin
_port
=
htons
((
uint16_t
)
port
);
}
else
if
(
sscanf
(
vec
->
ptr
,
"[%49[^]]]:%d%n"
,
buf
,
&
port
,
&
len
)
==
2
&&
inet_pton
(
AF_INET6
,
buf
,
&
so
->
lsa
.
sin6
.
sin6_addr
))
{
// IPv6 address, e.g. [3ffe:2a00:100:7031::1]:8080
so
->
lsa
.
sin6
.
sin6_family
=
AF_INET6
;
so
->
lsa
.
sin6
.
sin6
_port
=
htons
((
uint16_t
)
port
);
#endif
}
else
if
(
sscanf
(
vec
->
ptr
,
"%u%n"
,
&
port
,
&
len
)
==
1
)
{
// If only port is specified, bind to IPv4, INADDR_ANY
so
->
lsa
.
sin
.
sin_port
=
htons
((
uint16_t
)
port
);
}
else
{
port
=
len
=
0
;
// Parsing failure. Make port invalid.
}
return
1
;
ch
=
vec
->
ptr
[
len
];
// Next character after the port number
so
->
is_ssl
=
ch
==
's'
;
so
->
ssl_redir
=
ch
==
'r'
;
// Make sure the port is valid and vector ends with 's', 'r' or ','
return
is_valid_port
(
port
)
&&
(
ch
==
'\0'
||
ch
==
's'
||
ch
==
'r'
||
ch
==
','
);
}
static
int
set_ports_option
(
struct
mg_context
*
ctx
)
{
...
...
@@ -4548,7 +4557,7 @@ static int set_ports_option(struct mg_context *ctx) {
while
(
success
&&
(
list
=
next_option
(
list
,
&
vec
,
NULL
))
!=
NULL
)
{
if
(
!
parse_port_string
(
&
vec
,
&
so
))
{
cry
(
fc
(
ctx
),
"%s: %.*s: invalid port spec. Expecting list of: %s"
,
__func__
,
(
int
)
vec
.
len
,
vec
.
ptr
,
"[IP_ADDRESS:]PORT[s|
p
]"
);
__func__
,
(
int
)
vec
.
len
,
vec
.
ptr
,
"[IP_ADDRESS:]PORT[s|
r
]"
);
success
=
0
;
}
else
if
(
so
.
is_ssl
&&
ctx
->
ssl_ctx
==
NULL
)
{
cry
(
fc
(
ctx
),
"Cannot add SSL socket, is -ssl_certificate option set?"
);
...
...
@@ -4560,10 +4569,12 @@ static int set_ports_option(struct mg_context *ctx) {
setsockopt
(
so
.
sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
void
*
)
&
on
,
sizeof
(
on
))
!=
0
||
#if defined(USE_IPV6)
setsockopt
(
so
.
sock
,
IPPROTO_IPV6
,
IPV6_V6ONLY
,
(
void
*
)
&
off
,
sizeof
(
off
))
!=
0
||
(
so
.
lsa
.
sa
.
sa_family
==
AF_INET6
&&
setsockopt
(
so
.
sock
,
IPPROTO_IPV6
,
IPV6_V6ONLY
,
(
void
*
)
&
off
,
sizeof
(
off
))
!=
0
)
||
#endif
bind
(
so
.
sock
,
&
so
.
lsa
.
sa
,
sizeof
(
so
.
lsa
))
!=
0
||
bind
(
so
.
sock
,
&
so
.
lsa
.
sa
,
so
.
lsa
.
sa
.
sa_family
==
AF_INET
?
sizeof
(
so
.
lsa
.
sin
)
:
sizeof
(
so
.
lsa
))
!=
0
||
listen
(
so
.
sock
,
SOMAXCONN
)
!=
0
)
{
cry
(
fc
(
ctx
),
"%s: cannot bind to %.*s: %d"
,
__func__
,
(
int
)
vec
.
len
,
vec
.
ptr
,
ERRNO
);
...
...
test/unit_test.c
View file @
e53d0563
...
...
@@ -22,6 +22,14 @@
#define USE_WEBSOCKET
#define USE_LUA
#ifndef _WIN32
#define __cdecl
#define USE_IPV6
#endif
// USE_* definitions must be made before #include "mongoose.c" !
#include "mongoose.c"
static
int
s_total_tests
=
0
;
...
...
@@ -45,10 +53,6 @@ static int s_failed_tests = 0;
",127.0.0.1:" HTTPS_PORT "s" \
",127.0.0.1:" HTTP_PORT2
#ifndef _WIN32
#define __cdecl
#endif
static
void
test_parse_http_message
()
{
struct
mg_request_info
ri
;
char
req1
[]
=
"GET / HTTP/1.1
\r\n\r\n
"
;
...
...
@@ -719,7 +723,37 @@ static void test_strtoll(void) {
ASSERT
(
strtoll
(
"3566626116"
,
NULL
,
10
)
==
3566626116
);
}
static
void
test_parse_port_string
(
void
)
{
static
const
char
*
valid
[]
=
{
"1"
,
"1s"
,
"1r"
,
"1.2.3.4:1"
,
"1.2.3.4:1s"
,
"1.2.3.4:1r"
,
#if defined(USE_IPV6)
"[::1]:123"
,
"[3ffe:2a00:100:7031::1]:900"
,
#endif
NULL
};
static
const
char
*
invalid
[]
=
{
"0"
,
"99999"
,
"1k"
,
"1.2.3"
,
"1.2.3.4:"
,
"1.2.3.4:2p"
,
NULL
};
struct
socket
so
;
struct
vec
vec
;
int
i
;
for
(
i
=
0
;
valid
[
i
]
!=
NULL
;
i
++
)
{
vec
.
ptr
=
valid
[
i
];
vec
.
len
=
strlen
(
vec
.
ptr
);
ASSERT
(
parse_port_string
(
&
vec
,
&
so
)
!=
0
);
}
for
(
i
=
0
;
invalid
[
i
]
!=
NULL
;
i
++
)
{
vec
.
ptr
=
invalid
[
i
];
vec
.
len
=
strlen
(
vec
.
ptr
);
ASSERT
(
parse_port_string
(
&
vec
,
&
so
)
==
0
);
}
}
int
__cdecl
main
(
void
)
{
test_parse_port_string
();
test_mg_strcasestr
();
test_alloc_vprintf
();
test_base64_encode
();
...
...
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