summaryrefslogtreecommitdiff
path: root/other/sslmim/socket.cc
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/sslmim/socket.cc
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/sslmim/socket.cc')
-rw-r--r--other/sslmim/socket.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/other/sslmim/socket.cc b/other/sslmim/socket.cc
new file mode 100644
index 0000000..9097632
--- /dev/null
+++ b/other/sslmim/socket.cc
@@ -0,0 +1,144 @@
1/*
2 * Copyright (C) 2001 Sebastian Krahmer.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Sebastian Krahmer.
16 * 4. The name Sebastian Krahmer may not be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32#include <stdio.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35#include <netinet/in.h>
36#include <netinet/tcp.h>
37#include <string.h>
38#include <string>
39#include <errno.h>
40
41#include "socket.h"
42
43namespace NS_Socket {
44
45string error;
46
47const char *why()
48{
49 return error.c_str();
50}
51
52// disable Mr. Nagle's algorithm
53int nodelay(int sock)
54{
55 int one = 1;
56 socklen_t len = sizeof(one);
57
58 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, len) < 0) {
59 error = "NS_Socket::nodelay::setsockopt: ";
60 error += strerror(errno);
61 return -1;
62 }
63
64 return 0;
65}
66
67// make socket ready for port-reuse
68int reuse(int sock)
69{
70 int one = 1;
71 socklen_t len = sizeof(one);
72
73 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, len) < 0) {
74 error = "NS_Socket::reuse::setsockopt: ";
75 error += strerror(errno);
76 return -1;
77 }
78
79 return 0;
80}
81
82#ifdef FREEBSD
83#define LINUX22
84#endif
85
86// obtain real destination of connection
87int dstaddr(int sock, sockaddr_in *dst)
88{
89 if (!dst) {
90 error = "NS_Socket::dstaddr: dst == NULL";
91 return -1;
92 }
93
94#ifdef LINUX22
95 socklen_t size = sizeof(sockaddr_in);
96 if (getsockname(sock, (struct sockaddr*)dst, &size) < 0) {
97 error = "NS_Socket::dstaddr::getsockname: ";
98 error += strerror(errno);
99 return -1;
100 }
101#elif defined(LINUX24)
102#include <linux/netfilter_ipv4.h>
103 socklen_t size = sizeof(sockaddr_in);
104 if (getsockopt(sock, SOL_IP, SO_ORIGINAL_DST, dst, &size) < 0) {
105 error = "NS_Socket::dstaddr::getsockopt: ";
106 error += strerror(errno);
107 return -1;
108 }
109#else
110#error "Not supported on this OS yet."
111#endif
112 return 0;
113}
114
115int bind_local(int sock, int port, bool do_listen)
116{
117 struct sockaddr_in saddr;
118
119 memset(&saddr, 0, sizeof(saddr));
120
121 saddr.sin_port = htons(port);
122 saddr.sin_family = AF_INET;
123
124 if (reuse(sock) < 0)
125 return -1;
126
127 if (bind(sock, (struct sockaddr*)&saddr, sizeof(saddr)) < 0) {
128 error = "NS_Socket::bind_local::bind: ";
129 error += strerror(errno);
130 return -1;
131 }
132
133 if (do_listen) {
134 if (listen(sock, SOMAXCONN) < 0) {
135 error = "NS_Socket::bind_local::listen: ";
136 error += strerror(errno);
137 return -1;
138 }
139 }
140 return 0;
141}
142
143
144}; // namespace