MySQL 8.0.32
Source Code Documentation
sock_probe_win32.h
Go to the documentation of this file.
1/* Copyright (c) 2010, 2022, 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 == NULL) {
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 == NULL) return 1;
97
98 retval = GetAdaptersAddresses(family, flags, NULL, s->addresses, &out_buflen);
99
100 curr_addresses = s->addresses;
101 while (curr_addresses) {
102 PIP_ADAPTER_UNICAST_ADDRESS_LH curr_unicast_address;
103
104 IFDBG(D_TRANSPORT, STRLIT("Adapter status: ");
105 if (curr_addresses->OperStatus == IfOperStatusUp) STRLIT("UP");
106 else STRLIT("DOWN"););
107
108 curr_unicast_address = curr_addresses->FirstUnicastAddress;
109 while (curr_unicast_address) {
110 if (curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET ||
111 curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET6) {
113 }
114 curr_unicast_address = curr_unicast_address->Next;
115 }
116
117 curr_addresses = curr_addresses->Next;
118 }
119
120 return retval != NO_ERROR;
121}
122
123/* Close socket of sock_probe */
125 if (s && s->addresses) free(s->addresses);
126 free(s);
127}
128
129/* Return the number of IP interfaces on this machine.*/
131 if (s == NULL) {
132 return 0;
133 }
134 return s->number_of_interfaces;
135}
136
137/* Return TRUE if interface #count is running. */
138static bool_t is_if_running(sock_probe *s, int /* count */) {
139 if (s == NULL) {
140 return 0;
141 }
142 return 1; /* We will always report active because GetAdaptersAddresses */
143 /* always returns active interfaces. */
144}
145
147 PIP_ADAPTER_ADDRESSES network_interface;
148 PIP_ADAPTER_UNICAST_ADDRESS_LH network_address;
149};
151
153 int i = 0;
154 interface_info retval;
155 retval.network_address = NULL;
156 retval.network_interface = NULL;
157
159 PIP_ADAPTER_ADDRESSES curr_addresses = s->addresses;
160 while (curr_addresses && (i <= count)) {
161 PIP_ADAPTER_UNICAST_ADDRESS_LH curr_unicast_address =
162 curr_addresses->FirstUnicastAddress;
163 while (curr_unicast_address && (i <= count)) {
164 if (curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET ||
165 curr_unicast_address->Address.lpSockaddr->sa_family == AF_INET6) {
166 if (i == count) {
167 retval.network_address = curr_unicast_address;
168 retval.network_interface = curr_addresses;
169 }
170 i++;
171 }
172 curr_unicast_address = curr_unicast_address->Next;
173 }
174
175 curr_addresses = curr_addresses->Next;
176 }
177 }
178
179 return retval;
180}
181
182/* Return the sockaddr of interface #count. */
183/**
184 * @brief Get the sockaddr object that pertains to a certain interface index
185 * Depending of the addr_operation parameter value, it can be from:
186 * - Netmask
187 * - Physical Address
188 *
189 * @param s an initialized sock_probe structure
190 * @param count the interface index to return
191 * @param out the return value sockaddr. NULL in case of error.
192 * @param addr_operation either request the sockaddr for the physical address or
193 * for a netmask
194 */
195static void get_sockaddr(sock_probe *s, int count, struct sockaddr **out,
196 SockaddrOp addr_operation) {
198
199 if (s == NULL) {
200 *out = NULL;
201 }
202
205 *out = NULL;
206 return;
207 }
208
209 /* Let see what the function caller wants... */
210 switch (addr_operation) {
211 /* Return the interface address sockaddr */
213 *out = interface_info.network_address->Address.lpSockaddr;
214 break;
215 /* Return the interface address netmask */
217 /* Windows is the opposite of Nix.
218 While Nix has a sockaddr that contains the netmask,
219 and then you need to count the bits to see how many are
220 set, in case of Windows, you already have the number of bits that
221 are set in OnLinkPrefixLength field.
222 The issue with that is that then you need to convert them to a network
223 format. In case of IPv4, you have a method called
224 ConvertLengthToIpv4Mask. In case of V6 you need to do it by hand
225 setting the bits in the correct place of sin6_addr.s6_addr. */
226 if (interface_info.network_address->Address.lpSockaddr->sa_family ==
227 AF_INET) {
228 struct sockaddr_in *out_value =
229 (struct sockaddr_in *)xcom_malloc(sizeof(struct sockaddr_in));
230 ConvertLengthToIpv4Mask(
231 interface_info.network_address->OnLinkPrefixLength,
232 &out_value->sin_addr.s_addr);
233 *out = (struct sockaddr *)out_value;
234 } else {
235 long i, j;
236 struct sockaddr_in6 *out_value =
237 (struct sockaddr_in6 *)xcom_calloc(1, sizeof(struct sockaddr_in6));
238 for (i = interface_info.network_address->OnLinkPrefixLength, j = 0;
239 i > 0; i -= 8, ++j) {
240 out_value->sin6_addr.s6_addr[j] =
241 i >= 8 ? 0xff : (ULONG)((0xffU << (8 - i)));
242 }
243 *out = (struct sockaddr *)out_value;
244 }
245 break;
246 default:
247 break;
248 }
249}
250
252 struct sockaddr **out) {
254}
255
257 struct sockaddr **out) {
259}
260
261static char *get_if_name(sock_probe *s, int count) {
263
265 return NULL;
266 }
267
268 return interface_info.network_interface->AdapterName;
269}
#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:42
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:261
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:124
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:256
static bool_t is_if_running(sock_probe *s, int)
Definition: sock_probe_win32.h:138
static interface_info get_interface(sock_probe *s, int count)
Definition: sock_probe_win32.h:152
struct interface_info interface_info
Definition: sock_probe_win32.h:150
static void get_sockaddr_address(sock_probe *s, int count, struct sockaddr **out)
Definition: sock_probe_win32.h:251
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:195
static int number_of_interfaces(sock_probe *s)
Definition: sock_probe_win32.h:130
struct in_addr in_addr
Definition: sock_probe_win32.h:64
Definition: sock_probe_win32.h:146
PIP_ADAPTER_ADDRESSES network_interface
Definition: sock_probe_win32.h:147
PIP_ADAPTER_UNICAST_ADDRESS_LH network_address
Definition: sock_probe_win32.h:148
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...
#define NULL
Definition: types.h:54
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