1/* Network-related functions for internal library use.
2 Copyright (C) 2016-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#ifndef _NET_INTERNAL_H
20#define _NET_INTERNAL_H 1
21
22#include <arpa/inet.h>
23#include <stdbool.h>
24#include <stdint.h>
25#include <sys/time.h>
26#include <libc-diag.h>
27
28int __inet6_scopeid_pton (const struct in6_addr *address,
29 const char *scope, uint32_t *result);
30libc_hidden_proto (__inet6_scopeid_pton)
31
32
33/* IDNA conversion. These functions convert domain names between the
34 current multi-byte character set and the IDNA encoding. On
35 success, the result string is written to *RESULT (which the caller
36 has to free), and zero is returned. On error, an EAI_* error code
37 is returned (see <netdb.h>), and *RESULT is not changed. */
38int __idna_to_dns_encoding (const char *name, char **result);
39libc_hidden_proto (__idna_to_dns_encoding)
40int __idna_from_dns_encoding (const char *name, char **result);
41libc_hidden_proto (__idna_from_dns_encoding)
42
43
44/* Return value of __idna_name_classify below. */
45enum idna_name_classification
46{
47 idna_name_ascii, /* No non-ASCII characters. */
48 idna_name_nonascii, /* Non-ASCII characters, no backslash. */
49 idna_name_nonascii_backslash, /* Non-ASCII characters with backslash. */
50 idna_name_encoding_error, /* Decoding error. */
51 idna_name_memory_error, /* Memory allocation failure. */
52 idna_name_error, /* Other error during decoding. Check errno. */
53};
54
55/* Check the specified name for non-ASCII characters and backslashes
56 or encoding errors. */
57enum idna_name_classification __idna_name_classify (const char *name)
58 attribute_hidden;
59
60/* Deadline handling for enforcing timeouts.
61
62 Code should call __deadline_current_time to obtain the current time
63 and cache it locally. The cache needs updating after every
64 long-running or potentially blocking operation. Deadlines relative
65 to the current time can be computed using __deadline_from_timeval.
66 The deadlines may have to be recomputed in response to certain
67 events (such as an incoming packet), but they are absolute (not
68 relative to the current time). A timeout suitable for use with the
69 poll function can be computed from such a deadline using
70 __deadline_to_ms.
71
72 The fields in the structs defined belowed should only be used
73 within the implementation. */
74
75/* Cache of the current time. Used to compute deadlines from relative
76 timeouts and vice versa. */
77struct deadline_current_time
78{
79 struct timespec current;
80};
81
82/* Return the current time. Terminates the process if the current
83 time is not available. */
84struct deadline_current_time __deadline_current_time (void) attribute_hidden;
85
86/* Computed absolute deadline. */
87struct deadline
88{
89 struct timespec absolute;
90};
91
92
93/* For internal use only. */
94static inline bool
95__deadline_is_infinite (struct deadline deadline)
96{
97 return deadline.absolute.tv_nsec < 0;
98}
99
100/* GCC 8.3 and 9.2 both incorrectly report total_deadline
101 * (from sunrpc/clnt_udp.c) as maybe-uninitialized when tv_sec is 8 bytes
102 * (64-bits) wide on 32-bit systems. We have to set -Wmaybe-uninitialized
103 * here as it won't fix the error in sunrpc/clnt_udp.c.
104 * A GCC bug has been filed here:
105 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91691
106 */
107DIAG_PUSH_NEEDS_COMMENT;
108DIAG_IGNORE_NEEDS_COMMENT (9, "-Wmaybe-uninitialized");
109
110/* Return true if the current time is at the deadline or past it. */
111static inline bool
112__deadline_elapsed (struct deadline_current_time current,
113 struct deadline deadline)
114{
115 return !__deadline_is_infinite (deadline)
116 && (current.current.tv_sec > deadline.absolute.tv_sec
117 || (current.current.tv_sec == deadline.absolute.tv_sec
118 && current.current.tv_nsec >= deadline.absolute.tv_nsec));
119}
120
121/* Return the deadline which occurs first. */
122static inline struct deadline
123__deadline_first (struct deadline left, struct deadline right)
124{
125 if (__deadline_is_infinite (right)
126 || left.absolute.tv_sec < right.absolute.tv_sec
127 || (left.absolute.tv_sec == right.absolute.tv_sec
128 && left.absolute.tv_nsec < right.absolute.tv_nsec))
129 return left;
130 else
131 return right;
132}
133
134DIAG_POP_NEEDS_COMMENT;
135
136/* Add TV to the current time and return it. Returns a special
137 infinite absolute deadline on overflow. */
138struct deadline __deadline_from_timeval (struct deadline_current_time,
139 struct timeval tv) attribute_hidden;
140
141/* Compute the number of milliseconds until the specified deadline,
142 from the current time in the argument. The result is mainly for
143 use with poll. If the deadline has already passed, return 0. If
144 the result would overflow an int, return INT_MAX. */
145int __deadline_to_ms (struct deadline_current_time, struct deadline)
146 attribute_hidden;
147
148/* Return true if TV.tv_sec is non-negative and TV.tv_usec is in the
149 interval [0, 999999]. */
150static inline bool
151__is_timeval_valid_timeout (struct timeval tv)
152{
153 return tv.tv_sec >= 0 && tv.tv_usec >= 0 && tv.tv_usec < 1000 * 1000;
154}
155
156#endif /* _NET_INTERNAL_H */
157