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