Skip to content

Commit 4bfd1ad

Browse files
committed
Add missing v6utils file.
1 parent 3bf1601 commit 4bfd1ad

File tree

2 files changed

+317
-0
lines changed

2 files changed

+317
-0
lines changed

src/backend/libpq/v6util.c

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
#include "postgres.h"
2+
3+
#include <errno.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
#include <sys/stat.h>
7+
#include <sys/socket.h>
8+
#include <netdb.h>
9+
#include <netinet/in.h>
10+
#ifdef HAVE_NETINET_TCP_H
11+
#include <netinet/tcp.h>
12+
#endif
13+
#include <arpa/inet.h>
14+
#include <sys/file.h>
15+
16+
#include "libpq/libpq.h"
17+
#include "miscadmin.h"
18+
19+
20+
21+
22+
23+
24+
#ifdef HAVE_UNIX_SOCKETS
25+
static int ga_unix(const char* path, const struct addrinfo* hintsp,
26+
struct addrinfo** result);
27+
#endif /* HAVE_UNIX_SOCKETS */
28+
29+
30+
int getaddrinfo2(const char* hostname, const char* servname,
31+
const struct addrinfo* hintp, struct addrinfo **result)
32+
{
33+
#ifdef HAVE_UNIX_SOCKETS
34+
if( hintp != NULL && hintp->ai_family == AF_UNIX){
35+
return ga_unix(servname, hintp, result);
36+
}
37+
else {
38+
#endif /* HAVE_UNIX_SOCKETS */
39+
return getaddrinfo(hostname, servname, hintp, result);
40+
#ifdef HAVE_UNIX_SOCKETS
41+
}
42+
#endif /* HAVE_UNIX_SOCKETS */
43+
}
44+
45+
void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
46+
{
47+
#ifdef HAVE_UNIX_SOCKETS
48+
if(hint_ai_family == AF_UNIX){
49+
struct addrinfo *p;
50+
while(ai != NULL){
51+
p = ai;
52+
ai = ai->ai_next;
53+
free(p->ai_addr);
54+
free(p);
55+
}
56+
}
57+
else {
58+
#endif /* HAVE_UNIX_SOCKETS */
59+
freeaddrinfo(ai);
60+
#ifdef HAVE_UNIX_SOCKETS
61+
}
62+
#endif /* HAVE_UNIX_SOCKETS */
63+
}
64+
65+
66+
#ifdef HAVE_UNIX_SOCKETS
67+
/**
68+
* Bug: only one addrinfo is set even though hintsp is NULL or
69+
* ai_socktype is 0
70+
* AI_CANNONNAME does not support.
71+
*/
72+
static int ga_unix(const char* path, const struct addrinfo* hintsp,
73+
struct addrinfo** result)
74+
{
75+
struct addrinfo hints;
76+
struct addrinfo* aip;
77+
struct sockaddr_un* unp;
78+
memset(&hints, 0, sizeof(hints));
79+
80+
81+
if(hintsp == NULL){
82+
hints.ai_family = AF_UNIX;
83+
hints.ai_socktype = SOCK_STREAM;
84+
}
85+
else {
86+
memcpy(&hints, hintsp, sizeof(hints));
87+
}
88+
if(hints.ai_socktype == 0){
89+
hints.ai_socktype = SOCK_STREAM;
90+
}
91+
92+
if(!(hints.ai_family == AF_UNIX)){
93+
printf("hints.ai_family is invalied ga_unix()\n");
94+
return EAI_ADDRFAMILY;
95+
}
96+
97+
98+
aip = calloc(1, sizeof(struct addrinfo));
99+
if(aip == NULL){
100+
return EAI_MEMORY;
101+
}
102+
103+
aip->ai_family = AF_UNIX;
104+
aip->ai_socktype = hints.ai_socktype;
105+
aip->ai_protocol = hints.ai_protocol;
106+
aip->ai_next = NULL;
107+
aip->ai_canonname = NULL;
108+
*result = aip;
109+
110+
unp = calloc(1, sizeof(struct sockaddr_un));
111+
if(aip == NULL){
112+
return EAI_MEMORY;
113+
}
114+
115+
unp->sun_family = AF_UNIX;
116+
aip->ai_addr = (struct sockaddr*) unp;
117+
aip->ai_addrlen = sizeof(struct sockaddr_un);
118+
119+
if(strlen(path) >= sizeof(unp->sun_path)){
120+
return EAI_SERVICE;
121+
}
122+
strcpy(unp->sun_path, path);
123+
124+
#if SALEN
125+
unp->sun_len = sizeof(struct sockaddr_un);
126+
#endif /* SALEN */
127+
128+
if(hints.ai_flags & AI_PASSIVE){
129+
unlink(unp->sun_path);
130+
}
131+
132+
return 0;
133+
}
134+
#endif /* HAVE_UNIX_SOCKETS */
135+
136+
137+
138+
139+
140+
/**
141+
* SockAddr_ntop - set IP address string from SockAddr
142+
*
143+
* parameters... sa : SockAddr union
144+
* dst : buffer for address string
145+
* cnt : sizeof dst
146+
* v4conv: non-zero: if address is IPv4 mapped IPv6 address then
147+
* convert to IPv4 address.
148+
* returns... pointer to dst
149+
* if sa.sa_family is not AF_INET or AF_INET6 dst is set as empy string.
150+
*/
151+
char* SockAddr_ntop(const SockAddr* sa, char* dst, size_t cnt, int v4conv)
152+
{
153+
switch(sa->sa.sa_family){
154+
case AF_INET:
155+
inet_ntop(AF_INET, &sa->in.sin_addr, dst, cnt);
156+
break;
157+
case AF_INET6:
158+
inet_ntop(AF_INET6, &sa->in6.sin6_addr, dst, cnt);
159+
if(v4conv && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr) ){
160+
strcpy(dst, dst + 7);
161+
}
162+
break;
163+
default:
164+
dst[0] = '\0';
165+
break;
166+
}
167+
return dst;
168+
}
169+
170+
int SockAddr_pton(SockAddr* sa, const char* src, size_t cnt)
171+
{
172+
int i;
173+
int family = AF_INET;
174+
for(i = 0; i < cnt; i++){
175+
if(src[i] == ':'){
176+
family = AF_INET6;
177+
break;
178+
}
179+
}
180+
181+
sa->sa.sa_family = family;
182+
switch(family){
183+
case AF_INET:
184+
return inet_pton(AF_INET, src, &sa->in.sin_addr);
185+
case AF_INET6:
186+
return inet_pton(AF_INET6, src, &sa->in6.sin6_addr);
187+
break;
188+
default:
189+
return -1;
190+
}
191+
}
192+
193+
194+
195+
196+
/**
197+
* isAF_INETx - check to see if sa is AF_INET or AF_INET6
198+
*
199+
* parameters... sa : SockAddr union
200+
* returns...
201+
* if sa->sa.sa_famil is AF_INET or AF_INET6 then
202+
* return 1
203+
* else
204+
* return 0
205+
*/
206+
int isAF_INETx(const SockAddr* sa)
207+
{
208+
if(sa->sa.sa_family == AF_INET ||
209+
sa->sa.sa_family == AF_INET6
210+
){
211+
return 1;
212+
}
213+
else {
214+
return 0;
215+
}
216+
}
217+
218+
int isAF_INETx2(int family)
219+
{
220+
if(family == AF_INET ||
221+
family == AF_INET6
222+
){
223+
return 1;
224+
}
225+
else {
226+
return 0;
227+
}
228+
}
229+
230+
231+
int rangeSockAddr(const SockAddr* addr, const SockAddr* netaddr, const SockAddr* netmask)
232+
{
233+
if(addr->sa.sa_family == AF_INET){
234+
return rangeSockAddrAF_INET(addr, netaddr, netmask);
235+
}
236+
else if(addr->sa.sa_family == AF_INET6){
237+
return rangeSockAddrAF_INET6(addr, netaddr, netmask);
238+
}
239+
else {
240+
return 0;
241+
}
242+
}
243+
244+
int rangeSockAddrAF_INET(const SockAddr* addr, const SockAddr* netaddr,
245+
const SockAddr* netmask)
246+
{
247+
if(addr->sa.sa_family != AF_INET ||
248+
netaddr->sa.sa_family != AF_INET ||
249+
netmask->sa.sa_family != AF_INET ){
250+
return 0;
251+
}
252+
if( ((addr->in.sin_addr.s_addr ^ netaddr->in.sin_addr.s_addr ) &
253+
netmask->in.sin_addr.s_addr) == 0){
254+
return 1;
255+
}
256+
else {
257+
return 0;
258+
}
259+
}
260+
261+
int rangeSockAddrAF_INET6(const SockAddr* addr, const SockAddr* netaddr,
262+
const SockAddr* netmask)
263+
{
264+
int i;
265+
266+
if(IN6_IS_ADDR_V4MAPPED(&addr->in6.sin6_addr) ){
267+
SockAddr addr4;
268+
convSockAddr6to4(addr, &addr4);
269+
if(rangeSockAddrAF_INET(&addr4, netaddr, netmask)){
270+
return 1;
271+
}
272+
}
273+
274+
if(netaddr->sa.sa_family != AF_INET6 ||
275+
netmask->sa.sa_family != AF_INET6 ){
276+
return 0;
277+
}
278+
279+
for( i = 0; i < 16; i++){
280+
if( ((addr->in6.sin6_addr.s6_addr[i] ^ netaddr->in6.sin6_addr.s6_addr[i] ) &
281+
netmask->in6.sin6_addr.s6_addr[i] ) != 0){
282+
return 0;
283+
}
284+
}
285+
286+
return 1;
287+
}
288+
289+
void convSockAddr6to4(const SockAddr* src, SockAddr* dst)
290+
{
291+
char addr_str[INET6_ADDRSTRLEN];
292+
293+
dst->in.sin_family = AF_INET;
294+
dst->in.sin_port = src->in6.sin6_port;
295+
296+
dst->in.sin_addr.s_addr = src->in6.sin6_addr.s6_addr32[3];
297+
SockAddr_ntop(src, addr_str, INET6_ADDRSTRLEN, 0);
298+
}
299+
300+

src/include/libpq/v6util.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef V6UTIL_H
2+
#define V6UTIL_H
3+
void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
4+
int getaddrinfo2(const char* hostname, const char* servname,
5+
const struct addrinfo* hintp, struct addrinfo **result);
6+
char* SockAddr_ntop(const SockAddr* sa, char* dst, size_t cnt, int v4conv);
7+
int SockAddr_pton(SockAddr* sa, const char* src, size_t cnt);
8+
int isAF_INETx(const SockAddr* sa);
9+
int isAF_INETx2(int family);
10+
int rangeSockAddr(const SockAddr* addr, const SockAddr* netaddr, const SockAddr* netmask);
11+
int rangeSockAddrAF_INET(const SockAddr* addr, const SockAddr* netaddr,
12+
const SockAddr* netmask);
13+
int rangeSockAddrAF_INET6(const SockAddr* addr, const SockAddr* netaddr,
14+
const SockAddr* netmask);
15+
void convSockAddr6to4(const SockAddr* src, SockAddr* dst);
16+
17+
#endif /* V6UTIL_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy