MySQL 8.4.0
Source Code Documentation
sock_probe_win32.h
Go to the documentation of this file.
1/* Copyright (c) 2010, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24/**
25 Utility functions to check if a network address or name matches an
26 interface on the machine we are running on. This is useful to deduce
27 the node number from a list of network addresses or names. The node
28 number is the index of the list element which matches.
29*/
30
31#include <windows.h>
32
33#undef FD_SETSIZE
34#define FD_SETSIZE 256
35#include <assert.h>
36#include <errno.h>
37#include <iphlpapi.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <winsock2.h>
42#include <ws2tcpip.h>
43
44#define BSD_COMP
45
46#include "xcom/node_no.h"
47#include "xcom/simset.h"
48#include "xcom/sock_probe.h"
49#include "xcom/task.h"
50#include "xcom/task_debug.h"
51#include "xcom/task_net.h"
52#include "xcom/task_os.h"
53#include "xcom/xcom_base.h"
54#include "xcom/xcom_common.h"
55#include "xcom/xcom_memory.h"
56#include "xcom/xcom_profile.h"
57#include "xcom/xcom_transport.h"
58#include "xdr_gen/xcom_vp.h"
59
60#define WORKING_BUFFER_SIZE 1024 * 1024
61
62typedef struct sockaddr_in SOCKADDR_IN;
63typedef struct sockaddr sockaddr;
64
65typedef struct in_addr in_addr;
66
67/*
68 The sock_probe class provides utillity functions for
69 accessing the (set of) IP addresses on the current machine and
70 checking if one of these addresses matches a host.
71*/
72struct sock_probe {
73 PIP_ADAPTER_ADDRESSES addresses;
75};
76
77typedef struct sock_probe sock_probe;
78
79typedef enum SockaddrOp {
83
84/* Initialize socket probe */
86 ULONG flags = GAA_FLAG_INCLUDE_PREFIX, family = AF_UNSPEC, out_buflen = 0;
87 DWORD retval = 0;
88 PIP_ADAPTER_ADDRESSES curr_addresses;
89
90 if (s == nullptr) {
91 return 1;
92 }
93
94 out_buflen = WORKING_BUFFER_SIZE;
95
96 s->addresses = (IP_ADAPTER_ADDRESSES *)xcom_malloc(out_buflen);
97 if (s->addresses == nullptr) return 1;
98
99 retval =
100 GetAdaptersAddresses(family, flags, nullptr, s->addresses, &out_buflen);
101
102 curr_addresses = s->addresses;
103 while (curr_addresses) {
104 PIP_ADAPTER_UNICAST_ADDRESS_LH curr_unicast_address;
105
106 IFDBG(D_TRANSPORT, STRLIT("Adapter status: ");
107 if (curr_addresses->OperStatus == IfOperStatusUp) STRLIT("UP");
108 else STRLIT("DOWN"););
109
110 curr_unicast_address = curr_addresses->FirstUnicastAddress;
111 while (curr_unicast_address) {
112 if (curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET ||
113 curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET6) {
115 }
116 curr_unicast_address = curr_unicast_address->Next;
117 }
118
119 curr_addresses = curr_addresses->Next;
120 }
121
122 return retval != NO_ERROR;
123}
124
125/* Close socket of sock_probe */
127 if (s && s->addresses) free(s->addresses);
128 free(s);
129}
130
131/* Return the number of IP interfaces on this machine.*/
133 if (s == nullptr) {
134 return 0;
135 }
136 return s->number_of_interfaces;
137}
138
139/* Return TRUE if interface #count is running. */
140static bool_t is_if_running(sock_probe *s, int /* count */) {
141 if (s == nullptr) {
142 return 0;
143 }
144 return 1; /* We will always report active because GetAdaptersAddresses */
145 /* always returns active interfaces. */
146}
147
149 PIP_ADAPTER_ADDRESSES network_interface;
150 PIP_ADAPTER_UNICAST_ADDRESS_LH network_address;
151};
153
155 int i = 0;
156 interface_info retval;
157 retval.network_address = nullptr;
158 retval.network_interface = nullptr;
159
161 PIP_ADAPTER_ADDRESSES curr_addresses = s->addresses;
162 while (curr_addresses && (i <= count)) {
163 PIP_ADAPTER_UNICAST_ADDRESS_LH curr_unicast_address =
164 curr_addresses->FirstUnicastAddress;
165 while (curr_unicast_address && (i <= count)) {
166 if (curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET ||
167 curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET6) {
168 if (i == count) {
169 retval.network_address = curr_unicast_address;
170 retval.network_interface = curr_addresses;
171 }
172 i++;
173 }
174 curr_unicast_address = curr_unicast_address->Next;
175 }
176
177 curr_addresses = curr_addresses->Next;
178 }
179 }
180
181 return retval;
182}
183
184/* Return the sockaddr of interface #count. */
185/**
186 * @brief Get the sockaddr object that pertains to a certain interface index
187 * Depending of the addr_operation parameter value, it can be from:
188 * - Netmask
189 * - Physical Address
190 *
191 * @param s an initialized sock_probe structure
192 * @param count the interface index to return
193 * @param out the return value sockaddr. nullptr in case of error.
194 * @param addr_operation either request the sockaddr for the physical address or
195 * for a netmask
196 */
197static void get_sockaddr(sock_probe *s, int count, struct sockaddr **out,
198 SockaddrOp addr_operation) {
200
201 if (s == nullptr) {
202 *out = nullptr;
203 }
204
206 if (interface_info.network_interface == nullptr) {
207 *out = nullptr;
208 return;
209 }
210
211 /* Let see what the function caller wants... */
212 switch (addr_operation) {
213 /* Return the interface address sockaddr */
215 *out = interface_info.network_address->Address.lpSockaddr;
216 break;
217 /* Return the interface address netmask */
219 /* Windows is the opposite of Nix.
220 While Nix has a sockaddr that contains the netmask,
221 and then you need to count the bits to see how many are
222 set, in case of Windows, you already have the number of bits that
223 are set in OnLinkPrefixLength field.
224 The issue with that is that then you need to convert them to a network
225 format. In case of IPv4, you have a method called
226 ConvertLengthToIpv4Mask. In case of V6 you need to do it by hand
227 setting the bits in the correct place of sin6_addr.s6_addr. */
228 if (interface_info.network_address->Address.lpSockaddr->sa_family ==
229 AF_INET) {
230 struct sockaddr_in *out_value =
231 (struct sockaddr_in *)xcom_malloc(sizeof(struct sockaddr_in));
232 ConvertLengthToIpv4Mask(
233 interface_info.network_address->OnLinkPrefixLength,
234 &out_value->sin_addr.s_addr);
235 *out = (struct sockaddr *)out_value;
236 } else {
237 long i, j;
238 struct sockaddr_in6 *out_value =
239 (struct sockaddr_in6 *)xcom_calloc(1, sizeof(struct sockaddr_in6));
240 for (i = interface_info.network_address->OnLinkPrefixLength, j = 0;
241 i > 0; i -= 8, ++j) {
242 out_value->sin6_addr.s6_addr[j] =
243 i >= 8 ? 0xff : (ULONG)((0xffU << (8 - i)));
244 }
245 *out = (struct sockaddr *)out_value;
246 }
247 break;
248 default:
249 break;
250 }
251}
252
254 struct sockaddr **out) {
256}
257
259 struct sockaddr **out) {
261}
262
263static char *get_if_name(sock_probe *s, int count) {
265
266 if (interface_info.network_address == nullptr) {
267 return nullptr;
268 }
269
270 return interface_info.network_interface->AdapterName;
271}
#define IFDBG(mask, body)
Definition: gcs_debug.h:279
@ D_TRANSPORT
Definition: gcs_debug.h:178
#define STRLIT(x)
Definition: gcs_debug.h:316
static int flags[50]
Definition: hp_test1.cc:40
#define free(A)
Definition: lexyy.cc:915
static int count
Definition: myisam_ftdump.cc:45
SockaddrOp
Definition: sock_probe_ix.h:67
SockaddrOp
Definition: sock_probe_win32.h:79
@ kSockaddrOpAddress
Definition: sock_probe_win32.h:80
@ kSockaddrOpNetmask
Definition: sock_probe_win32.h:81
#define WORKING_BUFFER_SIZE
Definition: sock_probe_win32.h:60
static char * get_if_name(sock_probe *s, int count)
Definition: sock_probe_win32.h:263
static int init_sock_probe(sock_probe *s)
Definition: sock_probe_win32.h:85
struct sockaddr_in SOCKADDR_IN
Definition: sock_probe_win32.h:62
static void close_sock_probe(sock_probe *s)
Definition: sock_probe_win32.h:126
struct sockaddr sockaddr
Definition: sock_probe_win32.h:63
static void get_sockaddr_netmask(sock_probe *s, int count, struct sockaddr **out)
Definition: sock_probe_win32.h:258
static bool_t is_if_running(sock_probe *s, int)
Definition: sock_probe_win32.h:140
static interface_info get_interface(sock_probe *s, int count)
Definition: sock_probe_win32.h:154
struct interface_info interface_info
Definition: sock_probe_win32.h:152
static void get_sockaddr_address(sock_probe *s, int count, struct sockaddr **out)
Definition: sock_probe_win32.h:253
static void get_sockaddr(sock_probe *s, int count, struct sockaddr **out, SockaddrOp addr_operation)
Get the sockaddr object that pertains to a certain interface index Depending of the addr_operation pa...
Definition: sock_probe_win32.h:197
static int number_of_interfaces(sock_probe *s)
Definition: sock_probe_win32.h:132
struct in_addr in_addr
Definition: sock_probe_win32.h:65
Definition: sock_probe_win32.h:148
PIP_ADAPTER_ADDRESSES network_interface
Definition: sock_probe_win32.h:149
PIP_ADAPTER_UNICAST_ADDRESS_LH network_address
Definition: sock_probe_win32.h:150
Definition: sock_probe_ix.h:54
PIP_ADAPTER_ADDRESSES addresses
Definition: sock_probe_win32.h:73
int number_of_interfaces
Definition: sock_probe_win32.h:74
Rudimentary task system in portable C, based on Tom Duff's switch-based coroutine trick and a stack o...
int bool_t
Definition: types.h:35
#define idx_check_fail(x, limit)
Definition: xcom_common.h:71
static void * xcom_malloc(size_t size)
Definition: xcom_memory.h:46
static void * xcom_calloc(size_t nmemb, size_t size)
Definition: xcom_memory.h:54