diff --git a/libc/Android.mk b/libc/Android.mk index 683dfa9c5..d94dce231 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -39,7 +39,6 @@ endif # Define the common source files for all the libc instances # ========================================================= libc_common_src_files := \ - bionic/bindresvport.c \ bionic/ether_aton.c \ bionic/ether_ntoa.c \ bionic/fts.c \ @@ -173,6 +172,7 @@ libc_bionic_ndk_src_files := \ bionic/mremap.cpp \ bionic/NetdClientDispatch.cpp \ bionic/net_if.cpp \ + bionic/netinet_in.cpp \ bionic/open.cpp \ bionic/pathconf.cpp \ bionic/pause.cpp \ diff --git a/libc/bionic/bindresvport.c b/libc/bionic/netinet_in.cpp similarity index 63% rename from libc/bionic/bindresvport.c rename to libc/bionic/netinet_in.cpp index 5d9ad2bd8..dfa5d8d69 100644 --- a/libc/bionic/bindresvport.c +++ b/libc/bionic/netinet_in.cpp @@ -25,48 +25,46 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + +#include + #include #include #include -#include #include #include -#define START_PORT 600 -#define END_PORT IPPORT_RESERVED -#define NUM_PORTS (END_PORT - START_PORT) +constexpr int START_PORT = 600; +constexpr int END_PORT = IPPORT_RESERVED; +constexpr int NUM_PORTS = (END_PORT - START_PORT); -int bindresvport(int sd, struct sockaddr_in *sin) -{ - static short port; - struct sockaddr_in sin0; - int nn, ret; +int bindresvport(int sd, struct sockaddr_in* sin) { + sockaddr_in sin0; + if (sin == nullptr) { + memset(&sin0, 0, sizeof(sin0)); + sin = &sin0; + sin->sin_family = AF_INET; + } - if (sin == NULL) { - sin = &sin0; - memset( sin, 0, sizeof *sin ); - sin->sin_family = AF_INET; - } else if (sin->sin_family != AF_INET) { - errno = EPFNOSUPPORT; - return -1; - } + if (sin->sin_family != AF_INET) { + errno = EPFNOSUPPORT; + return -1; + } - if (port == 0) { - port = START_PORT + (getpid() % NUM_PORTS); - } + // TODO: thread safety! + static short port; + if (port == 0) { + port = START_PORT + (getpid() % NUM_PORTS); + } - for (nn = NUM_PORTS; nn > 0; nn--, port++) - { - if (port == END_PORT) - port = START_PORT; - - sin->sin_port = htons(port); - do { - ret = bind(sd, (struct sockaddr*)sin, sizeof(*sin)); - } while (ret < 0 && errno == EINTR); - - if (!ret) - break; - } - return ret; + for (size_t i = NUM_PORTS; i > 0; i--, port++) { + if (port == END_PORT) port = START_PORT; + sin->sin_port = htons(port); + int rc = TEMP_FAILURE_RETRY(bind(sd, reinterpret_cast(sin), sizeof(*sin))); + if (rc >= 0) return rc; + } + return -1; } + +const in6_addr in6addr_any = IN6ADDR_ANY_INIT; +const in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h index 44c7fc1a6..5f3d11f72 100644 --- a/libc/include/netinet/in.h +++ b/libc/include/netinet/in.h @@ -47,10 +47,10 @@ __BEGIN_DECLS typedef uint16_t in_port_t; typedef uint32_t in_addr_t; -extern int bindresvport (int sd, struct sockaddr_in *sin); +int bindresvport(int, struct sockaddr_in*); -static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; -static const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; +extern const struct in6_addr in6addr_any; +extern const struct in6_addr in6addr_loopback; __END_DECLS diff --git a/libc/libc.arm.brillo.map b/libc/libc.arm.brillo.map index 01541a9c0..80a88bd18 100644 --- a/libc/libc.arm.brillo.map +++ b/libc/libc.arm.brillo.map @@ -1240,6 +1240,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.arm.map b/libc/libc.arm.map index 25f53c9c6..18e51d432 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1240,6 +1240,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index 93bd94cc8..e1ccd4ef9 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1163,6 +1163,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.map.txt b/libc/libc.map.txt index dd0b9c047..b87a5e3ac 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1266,6 +1266,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.mips.brillo.map b/libc/libc.mips.brillo.map index 287c21436..57dfd50ba 100644 --- a/libc/libc.mips.brillo.map +++ b/libc/libc.mips.brillo.map @@ -1224,6 +1224,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.mips.map b/libc/libc.mips.map index 5c15a4239..ed72fd47a 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1224,6 +1224,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index 93bd94cc8..e1ccd4ef9 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1163,6 +1163,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.x86.brillo.map b/libc/libc.x86.brillo.map index 95fd7b8be..3dcf1ea5f 100644 --- a/libc/libc.x86.brillo.map +++ b/libc/libc.x86.brillo.map @@ -1223,6 +1223,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.x86.map b/libc/libc.x86.map index 6a1acba7a..1e44e2a56 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1223,6 +1223,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index 93bd94cc8..e1ccd4ef9 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1163,6 +1163,8 @@ LIBC_N { getifaddrs; if_freenameindex; if_nameindex; + in6addr_any; + in6addr_loopback; lockf; lockf64; preadv; diff --git a/tests/Android.mk b/tests/Android.mk index aba0871c5..0db63d952 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -65,8 +65,9 @@ libBionicStandardTests_src_files := \ malloc_test.cpp \ math_test.cpp \ mntent_test.cpp \ - net_if_test.cpp \ netdb_test.cpp \ + net_if_test.cpp \ + netinet_in_test.cpp \ netinet_udp_test.cpp \ pthread_test.cpp \ pty_test.cpp \ diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp new file mode 100644 index 000000000..a3377709f --- /dev/null +++ b/tests/netinet_in_test.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include + +TEST(netinet_in, bindresvport) { + // This isn't something we can usually test, so just check the symbol's there. + ASSERT_EQ(-1, bindresvport(-1, nullptr)); +} + +TEST(netinet_in, in6addr_any) { + in6_addr any = IN6ADDR_ANY_INIT; + ASSERT_EQ(0, memcmp(&any, &in6addr_any, sizeof(in6addr_any))); +} + +TEST(netinet_in, in6addr_loopback) { + in6_addr loopback = IN6ADDR_LOOPBACK_INIT; + ASSERT_EQ(0, memcmp(&loopback, &in6addr_loopback, sizeof(in6addr_loopback))); +}