REORG: sock: start to move some generic socket code to sock.c
The new file sock.c will contain generic code for standard sockets relying on file descriptors. We currently have way too much duplication between proto_uxst, proto_tcp, proto_sockpair and proto_udp. For now only get_src, get_dst and sock_create_server_socket were moved, and are used where appropriate.
This commit is contained in:
parent
1318034317
commit
18b7df7a2b
2
Makefile
2
Makefile
@ -820,7 +820,7 @@ OBJS = src/mux_fcgi.o src/mux_h1.o src/mux_h2.o src/backend.o \
|
||||
src/eb64tree.o src/dict.o src/shctx.o src/ebimtree.o \
|
||||
src/eb32tree.o src/ebtree.o src/dgram.o src/proto_udp.o \
|
||||
src/hpack-huff.o src/cfgparse-tcp.o src/base64.o src/version.o \
|
||||
src/cfgparse-unix.o
|
||||
src/cfgparse-unix.o src/sock.o
|
||||
|
||||
ifneq ($(TRACE),)
|
||||
OBJS += src/calltrace.o
|
||||
|
@ -31,7 +31,6 @@
|
||||
int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
|
||||
int tcp_pause_listener(struct listener *l);
|
||||
int tcp_connect_server(struct connection *conn, int flags);
|
||||
int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int tcp_is_foreign(int fd, sa_family_t family);
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
int udp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
|
||||
int udp_pause_listener(struct listener *l);
|
||||
int udp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int udp6_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int udp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
|
||||
#endif /* _PROTO_PROTO_UDP_H */
|
||||
|
42
include/haproxy/sock.h
Normal file
42
include/haproxy/sock.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* include/haproxy/sock.h
|
||||
* This file contains declarations for native (BSD-compatible) sockets.
|
||||
*
|
||||
* Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation, version 2.1
|
||||
* exclusively.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _HAPROXY_SOCK_H
|
||||
#define _HAPROXY_SOCK_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/connection-t.h>
|
||||
|
||||
int sock_create_server_socket(struct connection *conn);
|
||||
int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
|
||||
#endif /* _HAPROXY_SOCK_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
@ -39,6 +39,7 @@
|
||||
#include <haproxy/proto_tcp.h>
|
||||
#include <haproxy/protocol.h>
|
||||
#include <haproxy/proxy-t.h>
|
||||
#include <haproxy/sock.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
||||
|
||||
@ -62,7 +63,7 @@ static struct protocol proto_tcpv4 = {
|
||||
.bind_all = tcp_bind_listeners,
|
||||
.unbind_all = unbind_all_listeners,
|
||||
.enable_all = enable_all_listeners,
|
||||
.get_src = tcp_get_src,
|
||||
.get_src = sock_get_src,
|
||||
.get_dst = tcp_get_dst,
|
||||
.pause = tcp_pause_listener,
|
||||
.add = tcpv4_add_listener,
|
||||
@ -87,7 +88,7 @@ static struct protocol proto_tcpv6 = {
|
||||
.bind_all = tcp_bind_listeners,
|
||||
.unbind_all = unbind_all_listeners,
|
||||
.enable_all = enable_all_listeners,
|
||||
.get_src = tcp_get_src,
|
||||
.get_src = sock_get_src,
|
||||
.get_dst = tcp_get_dst,
|
||||
.pause = tcp_pause_listener,
|
||||
.add = tcpv6_add_listener,
|
||||
@ -226,22 +227,6 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* conn->dst MUST be valid */
|
||||
static int create_server_socket(struct connection *conn)
|
||||
{
|
||||
const struct netns_entry *ns = NULL;
|
||||
|
||||
#ifdef USE_NS
|
||||
if (objt_server(conn->target)) {
|
||||
if (__objt_server(conn->target)->flags & SRV_F_USE_NS_FROM_PP)
|
||||
ns = conn->proxy_netns;
|
||||
else
|
||||
ns = __objt_server(conn->target)->netns;
|
||||
}
|
||||
#endif
|
||||
return my_socketat(ns, conn->dst->ss_family, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function initiates a TCP connection establishment to the target assigned
|
||||
* to connection <conn> using (si->{target,dst}). A source address may be
|
||||
@ -310,7 +295,7 @@ int tcp_connect_server(struct connection *conn, int flags)
|
||||
return SF_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
fd = conn->handle.fd = create_server_socket(conn);
|
||||
fd = conn->handle.fd = sock_create_server_socket(conn);
|
||||
|
||||
if (fd == -1) {
|
||||
qfprintf(stderr, "Cannot get a server socket.\n");
|
||||
@ -594,21 +579,6 @@ int tcp_connect_server(struct connection *conn, int flags)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Retrieves the source address for the socket <fd>, with <dir> indicating
|
||||
* if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
|
||||
* success, -1 in case of error. The socket's source address is stored in
|
||||
* <sa> for <salen> bytes.
|
||||
*/
|
||||
int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
if (dir)
|
||||
return getsockname(fd, sa, &salen);
|
||||
else
|
||||
return getpeername(fd, sa, &salen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Retrieves the original destination address for the socket <fd>, with <dir>
|
||||
* indicating if we're a listener (=0) or an initiator (!=0). In the case of a
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <haproxy/proto_udp.h>
|
||||
#include <haproxy/proxy.h>
|
||||
#include <haproxy/server.h>
|
||||
#include <haproxy/sock.h>
|
||||
#include <haproxy/task.h>
|
||||
|
||||
static int udp_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
|
||||
@ -83,7 +84,7 @@ static struct protocol proto_udp6 = {
|
||||
.bind_all = udp_bind_listeners,
|
||||
.unbind_all = unbind_all_listeners,
|
||||
.enable_all = enable_all_listeners,
|
||||
.get_src = udp_get_src,
|
||||
.get_src = udp6_get_src,
|
||||
.get_dst = udp_get_dst,
|
||||
.pause = udp_pause_listener,
|
||||
.add = udp6_add_listener,
|
||||
@ -103,21 +104,29 @@ int udp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dir)
|
||||
ret = getsockname(fd, sa, &salen);
|
||||
else
|
||||
ret = getpeername(fd, sa, &salen);
|
||||
|
||||
if (!ret) {
|
||||
if (sa->sa_family == AF_INET)
|
||||
sa->sa_family = AF_CUST_UDP4;
|
||||
else if (sa->sa_family == AF_INET6)
|
||||
sa->sa_family = AF_CUST_UDP6;
|
||||
}
|
||||
ret = sock_get_src(fd, sa, salen, dir);
|
||||
if (!ret)
|
||||
sa->sa_family = AF_CUST_UDP4;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the source address for the socket <fd>, with <dir> indicating
|
||||
* if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
|
||||
* success, -1 in case of error. The socket's source address is stored in
|
||||
* <sa> for <salen> bytes.
|
||||
*/
|
||||
int udp6_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sock_get_src(fd, sa, salen, dir);
|
||||
if (!ret)
|
||||
sa->sa_family = AF_CUST_UDP6;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the original destination address for the socket <fd>, with <dir>
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <haproxy/listener.h>
|
||||
#include <haproxy/log.h>
|
||||
#include <haproxy/protocol.h>
|
||||
#include <haproxy/sock.h>
|
||||
#include <haproxy/time.h>
|
||||
#include <haproxy/tools.h>
|
||||
#include <haproxy/version.h>
|
||||
@ -44,8 +45,6 @@ static int uxst_unbind_listeners(struct protocol *proto);
|
||||
static int uxst_connect_server(struct connection *conn, int flags);
|
||||
static void uxst_add_listener(struct listener *listener, int port);
|
||||
static int uxst_pause_listener(struct listener *l);
|
||||
static int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
static int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
static struct protocol proto_unix = {
|
||||
@ -63,8 +62,8 @@ static struct protocol proto_unix = {
|
||||
.unbind_all = uxst_unbind_listeners,
|
||||
.enable_all = enable_all_listeners,
|
||||
.disable_all = disable_all_listeners,
|
||||
.get_src = uxst_get_src,
|
||||
.get_dst = uxst_get_dst,
|
||||
.get_src = sock_get_src,
|
||||
.get_dst = sock_get_dst,
|
||||
.pause = uxst_pause_listener,
|
||||
.add = uxst_add_listener,
|
||||
.listeners = LIST_HEAD_INIT(proto_unix.listeners),
|
||||
@ -77,35 +76,6 @@ INITCALL1(STG_REGISTER, protocol_register, &proto_unix);
|
||||
* 1) low-level socket functions
|
||||
********************************/
|
||||
|
||||
/*
|
||||
* Retrieves the source address for the socket <fd>, with <dir> indicating
|
||||
* if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
|
||||
* success, -1 in case of error. The socket's source address is stored in
|
||||
* <sa> for <salen> bytes.
|
||||
*/
|
||||
static int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
if (dir)
|
||||
return getsockname(fd, sa, &salen);
|
||||
else
|
||||
return getpeername(fd, sa, &salen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Retrieves the original destination address for the socket <fd>, with <dir>
|
||||
* indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
|
||||
* case of success, -1 in case of error. The socket's source address is stored
|
||||
* in <sa> for <salen> bytes.
|
||||
*/
|
||||
static int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
if (dir)
|
||||
return getpeername(fd, sa, &salen);
|
||||
else
|
||||
return getsockname(fd, sa, &salen);
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
* 2) listener-oriented functions
|
||||
|
85
src/sock.c
Normal file
85
src/sock.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Generic code for native (BSD-compatible) sockets
|
||||
*
|
||||
* Copyright 2000-2020 Willy Tarreau <w@1wt.eu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/connection.h>
|
||||
#include <haproxy/namespace.h>
|
||||
#include <haproxy/sock.h>
|
||||
#include <haproxy/tools.h>
|
||||
|
||||
|
||||
/* Create a socket to connect to the server in conn->dst (which MUST be valid),
|
||||
* using the configured namespace if needed, or the one passed by the proxy
|
||||
* protocol if required to do so. It ultimately calls socket() or socketat()
|
||||
* and returns the FD or error code.
|
||||
*/
|
||||
int sock_create_server_socket(struct connection *conn)
|
||||
{
|
||||
const struct netns_entry *ns = NULL;
|
||||
|
||||
#ifdef USE_NS
|
||||
if (objt_server(conn->target)) {
|
||||
if (__objt_server(conn->target)->flags & SRV_F_USE_NS_FROM_PP)
|
||||
ns = conn->proxy_netns;
|
||||
else
|
||||
ns = __objt_server(conn->target)->netns;
|
||||
}
|
||||
#endif
|
||||
return my_socketat(ns, conn->dst->ss_family, SOCK_STREAM, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the source address for the socket <fd>, with <dir> indicating
|
||||
* if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
|
||||
* success, -1 in case of error. The socket's source address is stored in
|
||||
* <sa> for <salen> bytes.
|
||||
*/
|
||||
int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
if (dir)
|
||||
return getsockname(fd, sa, &salen);
|
||||
else
|
||||
return getpeername(fd, sa, &salen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves the original destination address for the socket <fd>, with <dir>
|
||||
* indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
|
||||
* case of success, -1 in case of error. The socket's source address is stored
|
||||
* in <sa> for <salen> bytes.
|
||||
*/
|
||||
int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
|
||||
{
|
||||
if (dir)
|
||||
return getpeername(fd, sa, &salen);
|
||||
else
|
||||
return getsockname(fd, sa, &salen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* End:
|
||||
*/
|
Loading…
Reference in New Issue
Block a user