Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
265647e4
Commit
265647e4
authored
Sep 13, 2013
by
Charles-François Natali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #16201: socket: Use inet_pton()/inet_addr() instead of ad-hoc parsing for
numeric IP addresses.
parent
1db432fb
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
17 deletions
+66
-17
Lib/test/test_socket.py
Lib/test/test_socket.py
+14
-0
Modules/socketmodule.c
Modules/socketmodule.c
+52
-17
No files found.
Lib/test/test_socket.py
View file @
265647e4
...
...
@@ -757,6 +757,20 @@ class GeneralModuleTests(unittest.TestCase):
if
not
fqhn
in
all_host_names
:
self
.
fail
(
"Error testing host resolution mechanisms. (fqdn: %s, all: %s)"
%
(
fqhn
,
repr
(
all_host_names
)))
def
test_host_resolution
(
self
):
for
addr
in
[
'0.1.1.~1'
,
'1+.1.1.1'
,
'::1q'
,
'::1::2'
,
'1:1:1:1:1:1:1:1:1'
]:
self
.
assertRaises
(
OSError
,
socket
.
gethostbyname
,
addr
)
self
.
assertRaises
(
OSError
,
socket
.
gethostbyaddr
,
addr
)
for
addr
in
[
support
.
HOST
,
'10.0.0.1'
,
'255.255.255.255'
]:
self
.
assertEqual
(
socket
.
gethostbyname
(
addr
),
addr
)
# we don't test support.HOSTv6 because there's a chance it doesn't have
# a matching name entry (e.g. 'ip6-localhost')
for
host
in
[
support
.
HOST
]:
self
.
assertIn
(
host
,
socket
.
gethostbyaddr
(
host
)[
2
])
@
unittest
.
skipUnless
(
hasattr
(
socket
,
'sethostname'
),
"test needs socket.sethostname()"
)
@
unittest
.
skipUnless
(
hasattr
(
socket
,
'gethostname'
),
"test needs socket.gethostname()"
)
def
test_sethostname
(
self
):
...
...
Modules/socketmodule.c
View file @
265647e4
...
...
@@ -425,6 +425,10 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#define INVALID_SOCKET (-1)
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (-1)
#endif
/* XXX There's a problem here: *static* functions are not supposed to have
a Py prefix (or use CapitalizedWords). Later... */
...
...
@@ -787,8 +791,6 @@ setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af)
{
struct
addrinfo
hints
,
*
res
;
int
error
;
int
d1
,
d2
,
d3
,
d4
;
char
ch
;
memset
((
void
*
)
addr_ret
,
'\0'
,
sizeof
(
*
addr_ret
));
if
(
name
[
0
]
==
'\0'
)
{
...
...
@@ -837,7 +839,10 @@ setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af)
freeaddrinfo
(
res
);
return
siz
;
}
if
(
name
[
0
]
==
'<'
&&
strcmp
(
name
,
"<broadcast>"
)
==
0
)
{
/* special-case broadcast - inet_addr() below can return INADDR_NONE for
* this */
if
(
strcmp
(
name
,
"255.255.255.255"
)
==
0
||
strcmp
(
name
,
"<broadcast>"
)
==
0
)
{
struct
sockaddr_in
*
sin
;
if
(
af
!=
AF_INET
&&
af
!=
AF_UNSPEC
)
{
PyErr_SetString
(
PyExc_OSError
,
...
...
@@ -853,20 +858,53 @@ setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af)
sin
->
sin_addr
.
s_addr
=
INADDR_BROADCAST
;
return
sizeof
(
sin
->
sin_addr
);
}
if
(
sscanf
(
name
,
"%d.%d.%d.%d%c"
,
&
d1
,
&
d2
,
&
d3
,
&
d4
,
&
ch
)
==
4
&&
0
<=
d1
&&
d1
<=
255
&&
0
<=
d2
&&
d2
<=
255
&&
0
<=
d3
&&
d3
<=
255
&&
0
<=
d4
&&
d4
<=
255
)
{
struct
sockaddr_in
*
sin
;
sin
=
(
struct
sockaddr_in
*
)
addr_ret
;
s
in
->
sin_addr
.
s_addr
=
htonl
(
((
long
)
d1
<<
24
)
|
((
long
)
d2
<<
16
)
|
((
long
)
d3
<<
8
)
|
((
long
)
d4
<<
0
));
sin
->
sin_family
=
AF_INET
;
/* avoid a name resolution in case of numeric address */
#ifdef HAVE_INET_PTON
/* check for an IPv4 address */
if
(
af
==
AF_UNSPEC
||
af
==
AF_INET
)
{
s
truct
sockaddr_in
*
sin
=
(
struct
sockaddr_in
*
)
addr_ret
;
memset
(
sin
,
0
,
sizeof
(
*
sin
));
if
(
inet_pton
(
AF_INET
,
name
,
&
sin
->
sin_addr
)
>
0
)
{
sin
->
sin_family
=
AF_INET
;
#ifdef HAVE_SOCKADDR_SA_LEN
sin
->
sin_len
=
sizeof
(
*
sin
);
sin
->
sin_len
=
sizeof
(
*
sin
);
#endif
return
4
;
return
4
;
}
}
#ifdef ENABLE_IPV6
/* check for an IPv6 address - if the address contains a scope ID, we
* fallback to getaddrinfo(), which can handle translation from interface
* name to interface index */
if
((
af
==
AF_UNSPEC
||
af
==
AF_INET6
)
&&
!
strchr
(
name
,
'%'
))
{
struct
sockaddr_in6
*
sin
=
(
struct
sockaddr_in6
*
)
addr_ret
;
memset
(
sin
,
0
,
sizeof
(
*
sin
));
if
(
inet_pton
(
AF_INET6
,
name
,
&
sin
->
sin6_addr
)
>
0
)
{
sin
->
sin6_family
=
AF_INET6
;
#ifdef HAVE_SOCKADDR_SA_LEN
sin
->
sin6_len
=
sizeof
(
*
sin
);
#endif
return
16
;
}
}
#endif
/* ENABLE_IPV6 */
#else
/* HAVE_INET_PTON */
/* check for an IPv4 address */
if
(
af
==
AF_INET
||
af
==
AF_UNSPEC
)
{
struct
sockaddr_in
*
sin
=
(
struct
sockaddr_in
*
)
addr_ret
;
memset
(
sin
,
0
,
sizeof
(
*
sin
));
if
((
sin
->
sin_addr
.
s_addr
=
inet_addr
(
name
))
!=
INADDR_NONE
)
{
sin
->
sin_family
=
AF_INET
;
#ifdef HAVE_SOCKADDR_SA_LEN
sin
->
sin_len
=
sizeof
(
*
sin
);
#endif
return
4
;
}
}
#endif
/* HAVE_INET_PTON */
/* perform a name resolution */
memset
(
&
hints
,
0
,
sizeof
(
hints
));
hints
.
ai_family
=
af
;
Py_BEGIN_ALLOW_THREADS
...
...
@@ -4896,9 +4934,6 @@ binary format used in low-level network functions.");
static
PyObject
*
socket_inet_aton
(
PyObject
*
self
,
PyObject
*
args
)
{
#ifndef INADDR_NONE
#define INADDR_NONE (-1)
#endif
#ifdef HAVE_INET_ATON
struct
in_addr
buf
;
#endif
...
...
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