Mercurial > dropbear
annotate netio.c @ 1861:2b3a8026a6ce
Add re-exec for server
This allows ASLR to re-randomize the address
space for every connection, preventing some
vulnerabilities from being exploitable by
repeated probing.
Overhead (memory and time) is yet to be confirmed.
At present this is only enabled on Linux. Other BSD platforms
with fexecve() would probably also work though have not been tested.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 30 Jan 2022 10:14:56 +0800 |
parents | 5001e9c5641f |
children |
rev | line source |
---|---|
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
1 #include "netio.h" |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
2 #include "list.h" |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
3 #include "dbutil.h" |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
4 #include "session.h" |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
5 #include "debug.h" |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
6 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
7 struct dropbear_progress_connection { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
8 struct addrinfo *res; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
9 struct addrinfo *res_iter; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
10 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
11 char *remotehost, *remoteport; /* For error reporting */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
12 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
13 connect_callback cb; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
14 void *cb_data; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
15 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
16 struct Queue *writequeue; /* A queue of encrypted packets to send with TCP fastopen, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
17 or NULL. */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
18 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
19 int sock; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
20 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
21 char* errstring; |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
22 char *bind_address, *bind_port; |
1859
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
23 enum dropbear_prio prio; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
24 }; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
25 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
26 /* Deallocate a progress connection. Removes from the pending list if iter!=NULL. |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
27 Does not close sockets */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
28 static void remove_connect(struct dropbear_progress_connection *c, m_list_elem *iter) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
29 if (c->res) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
30 freeaddrinfo(c->res); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
31 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
32 m_free(c->remotehost); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
33 m_free(c->remoteport); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
34 m_free(c->errstring); |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
35 m_free(c->bind_address); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
36 m_free(c->bind_port); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
37 m_free(c); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
38 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
39 if (iter) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
40 list_remove(iter); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
41 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
42 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
43 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
44 static void cancel_callback(int result, int sock, void* UNUSED(data), const char* UNUSED(errstring)) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
45 if (result == DROPBEAR_SUCCESS) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
46 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
47 m_close(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
48 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
49 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
50 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
51 void cancel_connect(struct dropbear_progress_connection *c) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
52 c->cb = cancel_callback; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
53 c->cb_data = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
54 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
55 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
56 static void connect_try_next(struct dropbear_progress_connection *c) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
57 struct addrinfo *r; |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
58 int err; |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
59 int res = 0; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
60 int fastopen = 0; |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1152
diff
changeset
|
61 #if DROPBEAR_CLIENT_TCP_FAST_OPEN |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
62 struct msghdr message; |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
63 #endif |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
64 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
65 for (r = c->res_iter; r; r = r->ai_next) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
66 { |
1067
ce21d0bfaf98
dropbear_assert() rather than assert()
Matt Johnston <matt@ucc.asn.au>
parents:
1066
diff
changeset
|
67 dropbear_assert(c->sock == -1); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
68 |
1309
3b624ad2dc5e
make sure socket is of the right domain
Matt Johnston <matt@ucc.asn.au>
parents:
1152
diff
changeset
|
69 c->sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
70 if (c->sock < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
72 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
73 |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
74 if (c->bind_address || c->bind_port) { |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
75 /* bind to a source port/address */ |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
76 struct addrinfo hints; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
77 struct addrinfo *bindaddr = NULL; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
78 memset(&hints, 0, sizeof(hints)); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
79 hints.ai_socktype = SOCK_STREAM; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
80 hints.ai_family = r->ai_family; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
81 hints.ai_flags = AI_PASSIVE; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
82 |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
83 err = getaddrinfo(c->bind_address, c->bind_port, &hints, &bindaddr); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
84 if (err) { |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
85 int len = 100 + strlen(gai_strerror(err)); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
86 m_free(c->errstring); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
87 c->errstring = (char*)m_malloc(len); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
88 snprintf(c->errstring, len, "Error resolving bind address '%s' (port %s). %s", |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
89 c->bind_address, c->bind_port, gai_strerror(err)); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
90 TRACE(("Error resolving bind: %s", gai_strerror(err))) |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
91 close(c->sock); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
92 c->sock = -1; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
93 continue; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
94 } |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
95 res = bind(c->sock, bindaddr->ai_addr, bindaddr->ai_addrlen); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
96 freeaddrinfo(bindaddr); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
97 bindaddr = NULL; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
98 if (res < 0) { |
1465
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
99 /* failure */ |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
100 int keep_errno = errno; |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
101 int len = 300; |
1465
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
102 m_free(c->errstring); |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
103 c->errstring = m_malloc(len); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
104 snprintf(c->errstring, len, "Error binding local address '%s' (port %s). %s", |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
105 c->bind_address, c->bind_port, strerror(keep_errno)); |
1465
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
106 close(c->sock); |
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
107 c->sock = -1; |
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
108 continue; |
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
109 } |
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
110 } |
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
111 |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
112 ses.maxfd = MAX(ses.maxfd, c->sock); |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
113 set_sock_nodelay(c->sock); |
1859
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
114 set_sock_priority(c->sock, c->prio); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
115 setnonblocking(c->sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
116 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1152
diff
changeset
|
117 #if DROPBEAR_CLIENT_TCP_FAST_OPEN |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
118 fastopen = (c->writequeue != NULL); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
119 |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
120 if (fastopen) { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
121 memset(&message, 0x0, sizeof(message)); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
122 message.msg_name = r->ai_addr; |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
123 message.msg_namelen = r->ai_addrlen; |
1072 | 124 /* 6 is arbitrary, enough to hold initial packets */ |
1094
c45d65392c1a
Fix pointer differ in signess warnings [-Werror=pointer-sign]
Gaël PORTAY <gael.portay@gmail.com>
parents:
1078
diff
changeset
|
125 unsigned int iovlen = 6; /* Linux msg_iovlen is a size_t */ |
1076
d92597ef089e
fastopen code was totally broken
Matt Johnston <matt@ucc.asn.au>
parents:
1073
diff
changeset
|
126 struct iovec iov[6]; |
1072 | 127 packet_queue_to_iovec(c->writequeue, iov, &iovlen); |
1076
d92597ef089e
fastopen code was totally broken
Matt Johnston <matt@ucc.asn.au>
parents:
1073
diff
changeset
|
128 message.msg_iov = iov; |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
129 message.msg_iovlen = iovlen; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
130 res = sendmsg(c->sock, &message, MSG_FASTOPEN); |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
131 /* Returns EINPROGRESS if FASTOPEN wasn't available */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
132 if (res < 0) { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
133 if (errno != EINPROGRESS) { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
134 m_free(c->errstring); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
135 c->errstring = m_strdup(strerror(errno)); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
136 /* Not entirely sure which kind of errors are normal - 2.6.32 seems to |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
137 return EPIPE for any (nonblocking?) sendmsg(). just fall back */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
138 TRACE(("sendmsg tcp_fastopen failed, falling back. %s", strerror(errno))); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
139 /* No kernel MSG_FASTOPEN support. Fall back below */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
140 fastopen = 0; |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
141 /* Set to NULL to avoid trying again */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
142 c->writequeue = NULL; |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
143 } |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
144 } else { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
145 packet_queue_consume(c->writequeue, res); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
146 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
147 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
148 #endif |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
149 |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
150 /* Normal connect(), used as fallback for TCP fastopen too */ |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
151 if (!fastopen) { |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
152 res = connect(c->sock, r->ai_addr, r->ai_addrlen); |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
153 } |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
154 |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
155 if (res < 0 && errno != EINPROGRESS) { |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
156 /* failure */ |
1065
23103e1e9548
Fix error handling for dbclient async connect
Matt Johnston <matt@ucc.asn.au>
parents:
1053
diff
changeset
|
157 m_free(c->errstring); |
23103e1e9548
Fix error handling for dbclient async connect
Matt Johnston <matt@ucc.asn.au>
parents:
1053
diff
changeset
|
158 c->errstring = m_strdup(strerror(errno)); |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
159 close(c->sock); |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
160 c->sock = -1; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
161 continue; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
162 } else { |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
163 /* new connection was successful, wait for it to complete */ |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
164 break; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
165 } |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
166 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
167 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
168 if (r) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
169 c->res_iter = r->ai_next; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
170 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
171 c->res_iter = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
172 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
173 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
174 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
175 /* Connect via TCP to a host. */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
176 struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport, |
1859
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
177 connect_callback cb, void* cb_data, |
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
178 const char* bind_address, const char* bind_port, enum dropbear_prio prio) |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
179 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
180 struct dropbear_progress_connection *c = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
181 int err; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
182 struct addrinfo hints; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
183 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
184 c = m_malloc(sizeof(*c)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
185 c->remotehost = m_strdup(remotehost); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
186 c->remoteport = m_strdup(remoteport); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
187 c->sock = -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
188 c->cb = cb; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
189 c->cb_data = cb_data; |
1859
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
190 c->prio = prio; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
191 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
192 list_append(&ses.conn_pending, c); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
193 |
1801
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
194 #if DROPBEAR_FUZZ |
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
195 if (fuzz.fuzzing) { |
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
196 c->errstring = m_strdup("fuzzing connect_remote always fails"); |
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
197 return c; |
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
198 } |
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
199 #endif |
4983a6bc1f51
fuzz: fix crash in newtcpdirect(), don't close the channel too early
Matt Johnston <matt@ucc.asn.au>
parents:
1797
diff
changeset
|
200 |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
201 memset(&hints, 0, sizeof(hints)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
202 hints.ai_socktype = SOCK_STREAM; |
1078
b3b772646974
Should be AF_UNSPEC not PF_UNSPEC
Matt Johnston <matt@ucc.asn.au>
parents:
1076
diff
changeset
|
203 hints.ai_family = AF_UNSPEC; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
204 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
205 err = getaddrinfo(remotehost, remoteport, &hints, &c->res); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
206 if (err) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
207 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
208 len = 100 + strlen(gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
209 c->errstring = (char*)m_malloc(len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
210 snprintf(c->errstring, len, "Error resolving '%s' port '%s'. %s", |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
211 remotehost, remoteport, gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
212 TRACE(("Error resolving: %s", gai_strerror(err))) |
1053 | 213 } else { |
214 c->res_iter = c->res; | |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
215 } |
1465
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
216 |
1466
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
217 if (bind_address) { |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
218 c->bind_address = m_strdup(bind_address); |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
219 } |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
220 if (bind_port) { |
f787f60f8e45
bind to port as well with -b
Matt Johnston <matt@ucc.asn.au>
parents:
1465
diff
changeset
|
221 c->bind_port = m_strdup(bind_port); |
1465
f7a53832501d
cli_bind_address_connect
houseofkodai <karthik@houseofkodai.in>
parents:
1464
diff
changeset
|
222 } |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
223 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
224 return c; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
225 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
226 |
1050 | 227 void remove_connect_pending() { |
228 while (ses.conn_pending.first) { | |
229 struct dropbear_progress_connection *c = ses.conn_pending.first->item; | |
230 remove_connect(c, ses.conn_pending.first); | |
231 } | |
232 } | |
233 | |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
234 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
235 void set_connect_fds(fd_set *writefd) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
236 m_list_elem *iter; |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
237 iter = ses.conn_pending.first; |
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
238 while (iter) { |
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
239 m_list_elem *next_iter = iter->next; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
240 struct dropbear_progress_connection *c = iter->item; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
241 /* Set one going */ |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
242 while (c->res_iter && c->sock < 0) { |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
243 connect_try_next(c); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
244 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
245 if (c->sock >= 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
246 FD_SET(c->sock, writefd); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
247 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
248 /* Final failure */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
249 if (!c->errstring) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
250 c->errstring = m_strdup("unexpected failure"); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
251 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
252 c->cb(DROPBEAR_FAILURE, -1, c->cb_data, c->errstring); |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
253 remove_connect(c, iter); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
254 } |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
255 iter = next_iter; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
256 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
257 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
258 |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1426
diff
changeset
|
259 void handle_connect_fds(const fd_set *writefd) { |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
260 m_list_elem *iter; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
261 for (iter = ses.conn_pending.first; iter; iter = iter->next) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
262 int val; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
263 socklen_t vallen = sizeof(val); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
264 struct dropbear_progress_connection *c = iter->item; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
265 |
1053 | 266 if (c->sock < 0 || !FD_ISSET(c->sock, writefd)) { |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
267 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
268 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
269 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
270 TRACE(("handling %s port %s socket %d", c->remotehost, c->remoteport, c->sock)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
271 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
272 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &val, &vallen) != 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
273 TRACE(("handle_connect_fds getsockopt(%d) SO_ERROR failed: %s", c->sock, strerror(errno))) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
274 /* This isn't expected to happen - Unix has surprises though, continue gracefully. */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
275 m_close(c->sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
276 c->sock = -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
277 } else if (val != 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
278 /* Connect failed */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
279 TRACE(("connect to %s port %s failed.", c->remotehost, c->remoteport)) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
280 m_close(c->sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
281 c->sock = -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
282 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
283 m_free(c->errstring); |
1066 | 284 c->errstring = m_strdup(strerror(val)); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
285 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
286 /* New connection has been established */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
287 c->cb(DROPBEAR_SUCCESS, c->sock, c->cb_data, NULL); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
288 remove_connect(c, iter); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
289 TRACE(("leave handle_connect_fds - success")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
290 /* Must return here - remove_connect() invalidates iter */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
291 return; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
292 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
293 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
294 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
295 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
296 void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
297 c->writequeue = writequeue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
298 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
299 |
1459
06d52bcb8094
Pointer parameter could be declared as pointing to const
Francois Perrad <francois.perrad@gadz.org>
parents:
1426
diff
changeset
|
300 void packet_queue_to_iovec(const struct Queue *queue, struct iovec *iov, unsigned int *iov_count) { |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
301 struct Link *l; |
1034 | 302 unsigned int i; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
303 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
304 buffer *writebuf; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
305 |
1708 | 306 #ifndef IOV_MAX |
307 #if defined(__CYGWIN__) && !defined(UIO_MAXIOV) | |
1636
35a1e8de3aec
cygwin competibility fix (#64)
karel-m <1918753+karel-m@users.noreply.github.com>
parents:
1624
diff
changeset
|
308 #define IOV_MAX 1024 |
1708 | 309 #elif defined(__sgi) |
310 #define IOV_MAX 512 | |
311 #else | |
1636
35a1e8de3aec
cygwin competibility fix (#64)
karel-m <1918753+karel-m@users.noreply.github.com>
parents:
1624
diff
changeset
|
312 #define IOV_MAX UIO_MAXIOV |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
313 #endif |
1708 | 314 #endif |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
315 |
1072 | 316 *iov_count = MIN(MIN(queue->count, IOV_MAX), *iov_count); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
317 |
1073
88043f9d40bd
Fix when iov queue is large
Matt Johnston <matt@ucc.asn.au>
parents:
1072
diff
changeset
|
318 for (l = queue->head, i = 0; i < *iov_count; l = l->link, i++) |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
319 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
320 writebuf = (buffer*)l->item; |
1577
399d8eb961b5
get rid of unused packet_type in encrypted write queue
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
321 len = writebuf->len - writebuf->pos; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
322 dropbear_assert(len > 0); |
1577
399d8eb961b5
get rid of unused packet_type in encrypted write queue
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
323 TRACE2(("write_packet writev #%d len %d/%d", i, |
399d8eb961b5
get rid of unused packet_type in encrypted write queue
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
324 len, writebuf->len)) |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
325 iov[i].iov_base = buf_getptr(writebuf, len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
326 iov[i].iov_len = len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
327 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
328 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
329 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
330 void packet_queue_consume(struct Queue *queue, ssize_t written) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
331 buffer *writebuf; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
332 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
333 while (written > 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
334 writebuf = (buffer*)examine(queue); |
1577
399d8eb961b5
get rid of unused packet_type in encrypted write queue
Matt Johnston <matt@ucc.asn.au>
parents:
1558
diff
changeset
|
335 len = writebuf->len - writebuf->pos; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
336 if (len > written) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
337 /* partial buffer write */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
338 buf_incrpos(writebuf, written); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
339 written = 0; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
340 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
341 written -= len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
342 dequeue(queue); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
343 buf_free(writebuf); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
344 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
345 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
346 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
347 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
348 void set_sock_nodelay(int sock) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
349 int val; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
350 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
351 /* disable nagle */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
352 val = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
353 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
354 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
355 |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1152
diff
changeset
|
356 #if DROPBEAR_SERVER_TCP_FAST_OPEN |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
357 void set_listen_fast_open(int sock) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
358 int qlen = MAX(MAX_UNAUTH_PER_IP, 5); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
359 if (setsockopt(sock, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)) != 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
360 TRACE(("set_listen_fast_open failed for socket %d: %s", sock, strerror(errno))) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
361 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
362 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
363 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
364 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
365 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
366 void set_sock_priority(int sock, enum dropbear_prio prio) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
367 |
1034 | 368 int rc; |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
369 int val; |
1034 | 370 |
1558
2f64cb3d3007
- #if not #ifdef for DROPBEAR_FUZZ
Matt Johnston <matt@ucc.asn.au>
parents:
1511
diff
changeset
|
371 #if DROPBEAR_FUZZ |
1383
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
372 if (fuzz.fuzzing) { |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
373 TRACE(("fuzzing skips set_sock_prio")) |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
374 return; |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
375 } |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
376 #endif |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
377 /* Don't log ENOTSOCK errors so that this can harmlessly be called |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
378 * on a client '-J' proxy pipe */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
379 |
1858
ed3326f21888
Test for IP_TOS and hardcode DSCP values
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
380 #ifdef IP_TOS |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
381 /* Set the DSCP field for outbound IP packet priority. |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
382 rfc4594 has some guidance to meanings. |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
383 |
1859
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
384 We set AF21 as "Low-Latency" class for interactive (tty session, |
1d86a58fb52d
Leave non-interactive at default QoS class
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
385 also handshake/setup packets). Other traffic is left at the default. |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
386 |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
387 OpenSSH at present uses AF21/CS1, rationale |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
388 https://cvsweb.openbsd.org/src/usr.bin/ssh/readconf.c#rev1.284 |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
389 |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
390 Old Dropbear/OpenSSH and Debian/Ubuntu OpenSSH (at Jan 2022) use |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
391 IPTOS_LOWDELAY/IPTOS_THROUGHPUT |
1858
ed3326f21888
Test for IP_TOS and hardcode DSCP values
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
392 |
ed3326f21888
Test for IP_TOS and hardcode DSCP values
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
393 DSCP constants are from Linux headers, applicable to other platforms |
ed3326f21888
Test for IP_TOS and hardcode DSCP values
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
394 such as macos. |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
395 */ |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
396 if (prio == DROPBEAR_PRIO_LOWDELAY) { |
1858
ed3326f21888
Test for IP_TOS and hardcode DSCP values
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
397 val = 0x48; /* IPTOS_DSCP_AF21 */ |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
398 } else { |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
399 val = 0; /* default */ |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
400 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
401 #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
402 rc = setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (void*)&val, sizeof(val)); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
403 if (rc < 0 && errno != ENOTSOCK) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
404 TRACE(("Couldn't set IPV6_TCLASS (%s)", strerror(errno))); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
405 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
406 #endif |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
407 rc = setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&val, sizeof(val)); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
408 if (rc < 0 && errno != ENOTSOCK) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
409 TRACE(("Couldn't set IP_TOS (%s)", strerror(errno))); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
410 } |
1858
ed3326f21888
Test for IP_TOS and hardcode DSCP values
Matt Johnston <matt@ucc.asn.au>
parents:
1857
diff
changeset
|
411 #endif /* IP_TOS */ |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
412 |
1426
89f8c5960527
test for linux/pkt-sched.h rather than SO_PRIORITY
Matt Johnston <matt@ucc.asn.au>
parents:
1316
diff
changeset
|
413 #ifdef HAVE_LINUX_PKT_SCHED_H |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
414 /* Set scheduling priority within the local Linux network stack */ |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
415 if (prio == DROPBEAR_PRIO_LOWDELAY) { |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
416 val = TC_PRIO_INTERACTIVE; |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
417 } else { |
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
418 val = 0; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
419 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
420 /* linux specific, sets QoS class. see tc-prio(8) */ |
1857
6022df862942
Use DSCP for IP QoS traffic classes
Matt Johnston <matt@ucc.asn.au>
parents:
1801
diff
changeset
|
421 rc = setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &val, sizeof(val)); |
1704
d384bc2e5af3
Don't warn when SO_PRIORITY fails
Matt Johnston <matt@ucc.asn.au>
parents:
1636
diff
changeset
|
422 if (rc < 0 && errno != ENOTSOCK) { |
d384bc2e5af3
Don't warn when SO_PRIORITY fails
Matt Johnston <matt@ucc.asn.au>
parents:
1636
diff
changeset
|
423 TRACE(("Couldn't set SO_PRIORITY (%s)", strerror(errno))) |
d384bc2e5af3
Don't warn when SO_PRIORITY fails
Matt Johnston <matt@ucc.asn.au>
parents:
1636
diff
changeset
|
424 } |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
425 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
426 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
427 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
428 |
1464
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
429 /* from openssh/canohost.c avoid premature-optimization */ |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
430 int get_sock_port(int sock) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
431 struct sockaddr_storage from; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
432 socklen_t fromlen; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
433 char strport[NI_MAXSERV]; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
434 int r; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
435 |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
436 /* Get IP address of client. */ |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
437 fromlen = sizeof(from); |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
438 memset(&from, 0, sizeof(from)); |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
439 if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
440 TRACE(("getsockname failed: %d", errno)) |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
441 return 0; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
442 } |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
443 |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
444 /* Work around Linux IPv6 weirdness */ |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
445 if (from.ss_family == AF_INET6) |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
446 fromlen = sizeof(struct sockaddr_in6); |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
447 |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
448 /* Non-inet sockets don't have a port number. */ |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
449 if (from.ss_family != AF_INET && from.ss_family != AF_INET6) |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
450 return 0; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
451 |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
452 /* Return port number. */ |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
453 if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
454 strport, sizeof(strport), NI_NUMERICSERV)) != 0) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
455 TRACE(("netio.c/get_sock_port/getnameinfo NI_NUMERICSERV failed: %d", r)) |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
456 } |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
457 return atoi(strport); |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
458 } |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
459 |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
460 /* Listen on address:port. |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
461 * Special cases are address of "" listening on everything, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
462 * and address of NULL listening on localhost only. |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
463 * Returns the number of sockets bound on success, or -1 on failure. On |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
464 * failure, if errstring wasn't NULL, it'll be a newly malloced error |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
465 * string.*/ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
466 int dropbear_listen(const char* address, const char* port, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
467 int *socks, unsigned int sockcount, char **errstring, int *maxfd) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
468 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
469 struct addrinfo hints, *res = NULL, *res0 = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
470 int err; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
471 unsigned int nsock; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
472 struct linger linger; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
473 int val; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
474 int sock; |
1797
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
475 uint16_t *allocated_lport_p = NULL; |
1796
74f4a5987234
Update netio.c (#115)
Guillaume Picquet <guillaume.picquet@gls-france.com>
parents:
1786
diff
changeset
|
476 int allocated_lport = 0; |
74f4a5987234
Update netio.c (#115)
Guillaume Picquet <guillaume.picquet@gls-france.com>
parents:
1786
diff
changeset
|
477 |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
478 TRACE(("enter dropbear_listen")) |
1786
a3b39df57c8b
fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents:
1777
diff
changeset
|
479 |
a3b39df57c8b
fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents:
1777
diff
changeset
|
480 #if DROPBEAR_FUZZ |
a3b39df57c8b
fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents:
1777
diff
changeset
|
481 if (fuzz.fuzzing) { |
a3b39df57c8b
fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents:
1777
diff
changeset
|
482 return fuzz_dropbear_listen(address, port, socks, sockcount, errstring, maxfd); |
a3b39df57c8b
fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents:
1777
diff
changeset
|
483 } |
a3b39df57c8b
fuzz: add an always-failing dropbear_listen() replacement
Matt Johnston <matt@ucc.asn.au>
parents:
1777
diff
changeset
|
484 #endif |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
485 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
486 memset(&hints, 0, sizeof(hints)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
487 hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
488 hints.ai_socktype = SOCK_STREAM; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
489 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
490 /* for calling getaddrinfo: |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
491 address == NULL and !AI_PASSIVE: local loopback |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
492 address == NULL and AI_PASSIVE: all interfaces |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
493 address != NULL: whatever the address says */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
494 if (!address) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
495 TRACE(("dropbear_listen: local loopback")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
496 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
497 if (address[0] == '\0') { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
498 TRACE(("dropbear_listen: all interfaces")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
499 address = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
500 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
501 hints.ai_flags = AI_PASSIVE; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
502 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
503 err = getaddrinfo(address, port, &hints, &res0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
504 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
505 if (err) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
506 if (errstring != NULL && *errstring == NULL) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
507 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
508 len = 20 + strlen(gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
509 *errstring = (char*)m_malloc(len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
510 snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
511 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
512 if (res0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
513 freeaddrinfo(res0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
514 res0 = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
515 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
516 TRACE(("leave dropbear_listen: failed resolving")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
517 return -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
518 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
519 |
1797
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
520 /* When listening on server-assigned-port 0 |
1464
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
521 * the assigned ports may differ for address families (v4/v6) |
1797
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
522 * causing problems for tcpip-forward. |
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
523 * Caller can do a get_socket_address to discover assigned-port |
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
524 * hence, use same port for all address families */ |
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
525 allocated_lport = 0; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
526 nsock = 0; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
527 for (res = res0; res != NULL && nsock < sockcount; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
528 res = res->ai_next) { |
1464
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
529 if (allocated_lport > 0) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
530 if (AF_INET == res->ai_family) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
531 allocated_lport_p = &((struct sockaddr_in *)res->ai_addr)->sin_port; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
532 } else if (AF_INET6 == res->ai_family) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
533 allocated_lport_p = &((struct sockaddr_in6 *)res->ai_addr)->sin6_port; |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
534 } |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
535 *allocated_lport_p = htons(allocated_lport); |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
536 } |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
537 |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
538 /* Get a socket */ |
1797
f680a19bd559
Small cleanups of netio allocated port
Matt Johnston <matt@ucc.asn.au>
parents:
1796
diff
changeset
|
539 socks[nsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
540 sock = socks[nsock]; /* For clarity */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
541 if (sock < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
542 err = errno; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
543 TRACE(("socket() failed")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
544 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
545 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
546 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
547 /* Various useful socket options */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
548 val = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
549 /* set to reuse, quick timeout */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
550 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
551 linger.l_onoff = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
552 linger.l_linger = 5; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
553 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
554 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
555 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
556 if (res->ai_family == AF_INET6) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
557 int on = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
558 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
559 &on, sizeof(on)) == -1) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
560 dropbear_log(LOG_WARNING, "Couldn't set IPV6_V6ONLY"); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
561 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
562 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
563 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
564 set_sock_nodelay(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
565 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
566 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
567 err = errno; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
568 close(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
569 TRACE(("bind(%s) failed", port)) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
570 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
571 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
572 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
573 if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
574 err = errno; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
575 close(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
576 TRACE(("listen() failed")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
577 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
578 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
579 |
1464
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
580 if (0 == allocated_lport) { |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
581 allocated_lport = get_sock_port(sock); |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
582 } |
ad637c9e0f6f
Server chosen tcpfwd ports (#43)
houseofkodai <karthik@houseofkodai.in>
parents:
1459
diff
changeset
|
583 |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
584 *maxfd = MAX(*maxfd, sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
585 nsock++; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
586 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
587 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
588 if (res0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
589 freeaddrinfo(res0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
590 res0 = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
591 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
592 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
593 if (nsock == 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
594 if (errstring != NULL && *errstring == NULL) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
595 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
596 len = 20 + strlen(strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
597 *errstring = (char*)m_malloc(len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
598 snprintf(*errstring, len, "Error listening: %s", strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
599 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
600 TRACE(("leave dropbear_listen: failure, %s", strerror(err))) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
601 return -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
602 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
603 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
604 TRACE(("leave dropbear_listen: success, %d socks bound", nsock)) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
605 return nsock; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
606 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
607 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
608 void get_socket_address(int fd, char **local_host, char **local_port, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
609 char **remote_host, char **remote_port, int host_lookup) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
610 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
611 struct sockaddr_storage addr; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
612 socklen_t addrlen; |
1383
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
613 |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
614 #if DROPBEAR_FUZZ |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
615 if (fuzz.fuzzing) { |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
616 fuzz_get_socket_address(fd, local_host, local_port, remote_host, remote_port, host_lookup); |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
617 return; |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
618 } |
f03cfe9c76ac
Disable setnonblocking(), get_socket_address(), set_sock_priority()
Matt Johnston <matt@ucc.asn.au>
parents:
1357
diff
changeset
|
619 #endif |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
620 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
621 if (local_host || local_port) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
622 addrlen = sizeof(addr); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
623 if (getsockname(fd, (struct sockaddr*)&addr, &addrlen) < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
624 dropbear_exit("Failed socket address: %s", strerror(errno)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
625 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
626 getaddrstring(&addr, local_host, local_port, host_lookup); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
627 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
628 if (remote_host || remote_port) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
629 addrlen = sizeof(addr); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
630 if (getpeername(fd, (struct sockaddr*)&addr, &addrlen) < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
631 dropbear_exit("Failed socket address: %s", strerror(errno)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
632 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
633 getaddrstring(&addr, remote_host, remote_port, host_lookup); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
634 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
635 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
636 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
637 /* Return a string representation of the socket address passed. The return |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
638 * value is allocated with malloc() */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
639 void getaddrstring(struct sockaddr_storage* addr, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
640 char **ret_host, char **ret_port, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
641 int host_lookup) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
642 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
643 char host[NI_MAXHOST+1], serv[NI_MAXSERV+1]; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
644 unsigned int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
645 int ret; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
646 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
647 int flags = NI_NUMERICSERV | NI_NUMERICHOST; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
648 |
1499
2d450c1056e3
options: Complete the transition to numeric toggles (`#if')
Michael Witten <mfwitten@gmail.com>
parents:
1466
diff
changeset
|
649 #if !DO_HOST_LOOKUP |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
650 host_lookup = 0; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
651 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
652 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
653 if (host_lookup) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
654 flags = NI_NUMERICSERV; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
655 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
656 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
657 len = sizeof(struct sockaddr_storage); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
658 /* Some platforms such as Solaris 8 require that len is the length |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
659 * of the specific structure. Some older linux systems (glibc 2.1.3 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
660 * such as debian potato) have sockaddr_storage.__ss_family instead |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
661 * but we'll ignore them */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
662 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
663 if (addr->ss_family == AF_INET) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
664 len = sizeof(struct sockaddr_in); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
665 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
666 #ifdef AF_INET6 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
667 if (addr->ss_family == AF_INET6) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
668 len = sizeof(struct sockaddr_in6); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
669 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
670 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
671 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
672 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
673 ret = getnameinfo((struct sockaddr*)addr, len, host, sizeof(host)-1, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
674 serv, sizeof(serv)-1, flags); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
675 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
676 if (ret != 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
677 if (host_lookup) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
678 /* On some systems (Darwin does it) we get EINTR from getnameinfo |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
679 * somehow. Eew. So we'll just return the IP, since that doesn't seem |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
680 * to exhibit that behaviour. */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
681 getaddrstring(addr, ret_host, ret_port, 0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
682 return; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
683 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
684 /* if we can't do a numeric lookup, something's gone terribly wrong */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
685 dropbear_exit("Failed lookup: %s", gai_strerror(ret)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
686 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
687 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
688 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
689 if (ret_host) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
690 *ret_host = m_strdup(host); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
691 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
692 if (ret_port) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
693 *ret_port = m_strdup(serv); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
694 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
695 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
696 |