Willy Tarreau | 18b7df7 | 2020-08-28 12:07:22 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Generic code for native (BSD-compatible) sockets |
| 3 | * |
| 4 | * Copyright 2000-2020 Willy Tarreau <w@1wt.eu> |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU General Public License |
| 8 | * as published by the Free Software Foundation; either version |
| 9 | * 2 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | */ |
| 12 | |
| 13 | #include <ctype.h> |
| 14 | #include <errno.h> |
| 15 | #include <fcntl.h> |
| 16 | #include <stdio.h> |
| 17 | #include <stdlib.h> |
| 18 | #include <string.h> |
| 19 | #include <time.h> |
| 20 | |
| 21 | #include <sys/param.h> |
| 22 | #include <sys/socket.h> |
| 23 | #include <sys/types.h> |
| 24 | |
| 25 | #include <haproxy/api.h> |
| 26 | #include <haproxy/connection.h> |
| 27 | #include <haproxy/namespace.h> |
| 28 | #include <haproxy/sock.h> |
| 29 | #include <haproxy/tools.h> |
| 30 | |
| 31 | |
| 32 | /* Create a socket to connect to the server in conn->dst (which MUST be valid), |
| 33 | * using the configured namespace if needed, or the one passed by the proxy |
| 34 | * protocol if required to do so. It ultimately calls socket() or socketat() |
| 35 | * and returns the FD or error code. |
| 36 | */ |
| 37 | int sock_create_server_socket(struct connection *conn) |
| 38 | { |
| 39 | const struct netns_entry *ns = NULL; |
| 40 | |
| 41 | #ifdef USE_NS |
| 42 | if (objt_server(conn->target)) { |
| 43 | if (__objt_server(conn->target)->flags & SRV_F_USE_NS_FROM_PP) |
| 44 | ns = conn->proxy_netns; |
| 45 | else |
| 46 | ns = __objt_server(conn->target)->netns; |
| 47 | } |
| 48 | #endif |
| 49 | return my_socketat(ns, conn->dst->ss_family, SOCK_STREAM, 0); |
| 50 | } |
| 51 | |
| 52 | /* |
| 53 | * Retrieves the source address for the socket <fd>, with <dir> indicating |
| 54 | * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of |
| 55 | * success, -1 in case of error. The socket's source address is stored in |
| 56 | * <sa> for <salen> bytes. |
| 57 | */ |
| 58 | int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir) |
| 59 | { |
| 60 | if (dir) |
| 61 | return getsockname(fd, sa, &salen); |
| 62 | else |
| 63 | return getpeername(fd, sa, &salen); |
| 64 | } |
| 65 | |
| 66 | /* |
| 67 | * Retrieves the original destination address for the socket <fd>, with <dir> |
| 68 | * indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in |
| 69 | * case of success, -1 in case of error. The socket's source address is stored |
| 70 | * in <sa> for <salen> bytes. |
| 71 | */ |
| 72 | int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir) |
| 73 | { |
| 74 | if (dir) |
| 75 | return getpeername(fd, sa, &salen); |
| 76 | else |
| 77 | return getsockname(fd, sa, &salen); |
| 78 | } |
| 79 | |
| 80 | /* |
| 81 | * Local variables: |
| 82 | * c-indent-level: 8 |
| 83 | * c-basic-offset: 8 |
| 84 | * End: |
| 85 | */ |