Mercurial > dropbear
annotate netio.c @ 1156:a8f4dade70e5
avoid getpass when not used
some systems (like android's bionic) do not provide getpass. you can
disable ENABLE_CLI_PASSWORD_AUTH & ENABLE_CLI_INTERACT_AUTH to avoid
its use (and rely on pubkey auth), but the link still fails because
the support file calls getpass. do not define this func if both of
those auth methods are not used.
author | Mike Frysinger <vapier@gentoo.org> |
---|---|
date | Wed, 21 Oct 2015 22:39:55 +0800 |
parents | 57d09741d46d |
children | 750ec4ec4cbe 3b624ad2dc5e |
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; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
22 }; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
23 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
24 /* 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
|
25 Does not close sockets */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
26 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
|
27 if (c->res) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
28 freeaddrinfo(c->res); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
29 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
30 m_free(c->remotehost); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
31 m_free(c->remoteport); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
32 m_free(c->errstring); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
33 m_free(c); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
34 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
35 if (iter) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
36 list_remove(iter); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
37 } |
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 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
40 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
|
41 if (result == DROPBEAR_SUCCESS) |
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 m_close(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
44 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
45 } |
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 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
|
48 c->cb = cancel_callback; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
49 c->cb_data = NULL; |
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 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
52 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
|
53 struct addrinfo *r; |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
54 int res = 0; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
55 int fastopen = 0; |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
56 #ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
57 struct msghdr message; |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
58 #endif |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
59 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
60 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
|
61 { |
1067
ce21d0bfaf98
dropbear_assert() rather than assert()
Matt Johnston <matt@ucc.asn.au>
parents:
1066
diff
changeset
|
62 dropbear_assert(c->sock == -1); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
63 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
64 c->sock = socket(c->res_iter->ai_family, c->res_iter->ai_socktype, c->res_iter->ai_protocol); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
65 if (c->sock < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
66 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
67 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
68 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
69 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
|
70 set_sock_nodelay(c->sock); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
71 setnonblocking(c->sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
72 |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
73 #ifdef DROPBEAR_CLIENT_TCP_FAST_OPEN |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
74 fastopen = (c->writequeue != NULL); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
75 |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
76 if (fastopen) { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
77 memset(&message, 0x0, sizeof(message)); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
78 message.msg_name = r->ai_addr; |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
79 message.msg_namelen = r->ai_addrlen; |
1072 | 80 /* 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
|
81 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
|
82 struct iovec iov[6]; |
1072 | 83 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
|
84 message.msg_iov = iov; |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
85 message.msg_iovlen = iovlen; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
86 res = sendmsg(c->sock, &message, MSG_FASTOPEN); |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
87 /* Returns EINPROGRESS if FASTOPEN wasn't available */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
88 if (res < 0) { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
89 if (errno != EINPROGRESS) { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
90 m_free(c->errstring); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
91 c->errstring = m_strdup(strerror(errno)); |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
92 /* 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
|
93 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
|
94 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
|
95 /* No kernel MSG_FASTOPEN support. Fall back below */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
96 fastopen = 0; |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
97 /* Set to NULL to avoid trying again */ |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
98 c->writequeue = NULL; |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
99 } |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
100 } else { |
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
101 packet_queue_consume(c->writequeue, res); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
102 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
103 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
104 #endif |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
105 |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
106 /* Normal connect(), used as fallback for TCP fastopen too */ |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
107 if (!fastopen) { |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
108 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
|
109 } |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
110 |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
111 if (res < 0 && errno != EINPROGRESS) { |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
112 /* failure */ |
1065
23103e1e9548
Fix error handling for dbclient async connect
Matt Johnston <matt@ucc.asn.au>
parents:
1053
diff
changeset
|
113 m_free(c->errstring); |
23103e1e9548
Fix error handling for dbclient async connect
Matt Johnston <matt@ucc.asn.au>
parents:
1053
diff
changeset
|
114 c->errstring = m_strdup(strerror(errno)); |
1033
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
115 close(c->sock); |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
116 c->sock = -1; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
117 continue; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
118 } else { |
1035
8ed1d37e75a6
get rid of some unnecessary code
Matt Johnston <matt@ucc.asn.au>
parents:
1034
diff
changeset
|
119 /* 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
|
120 break; |
ca71904cf3ee
Fixes for backwards compatibility
Matt Johnston <matt@ucc.asn.au>
parents:
1032
diff
changeset
|
121 } |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
122 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
123 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
124 if (r) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
125 c->res_iter = r->ai_next; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
126 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
127 c->res_iter = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
128 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
129 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
130 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
131 /* Connect via TCP to a host. */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
132 struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
133 connect_callback cb, void* cb_data) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
134 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
135 struct dropbear_progress_connection *c = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
136 int err; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
137 struct addrinfo hints; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
138 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
139 c = m_malloc(sizeof(*c)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
140 c->remotehost = m_strdup(remotehost); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
141 c->remoteport = m_strdup(remoteport); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
142 c->sock = -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
143 c->cb = cb; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
144 c->cb_data = cb_data; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
145 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
146 list_append(&ses.conn_pending, c); |
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 memset(&hints, 0, sizeof(hints)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
149 hints.ai_socktype = SOCK_STREAM; |
1078
b3b772646974
Should be AF_UNSPEC not PF_UNSPEC
Matt Johnston <matt@ucc.asn.au>
parents:
1076
diff
changeset
|
150 hints.ai_family = AF_UNSPEC; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
151 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
152 err = getaddrinfo(remotehost, remoteport, &hints, &c->res); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
153 if (err) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
154 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
155 len = 100 + strlen(gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
156 c->errstring = (char*)m_malloc(len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
157 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
|
158 remotehost, remoteport, gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
159 TRACE(("Error resolving: %s", gai_strerror(err))) |
1053 | 160 } else { |
161 c->res_iter = c->res; | |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
162 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
163 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
164 return c; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
165 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
166 |
1050 | 167 void remove_connect_pending() { |
168 while (ses.conn_pending.first) { | |
169 struct dropbear_progress_connection *c = ses.conn_pending.first->item; | |
170 remove_connect(c, ses.conn_pending.first); | |
171 } | |
172 } | |
173 | |
1032
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 void set_connect_fds(fd_set *writefd) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
176 m_list_elem *iter; |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
177 TRACE(("enter set_connect_fds")) |
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
178 iter = ses.conn_pending.first; |
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
179 while (iter) { |
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
180 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
|
181 struct dropbear_progress_connection *c = iter->item; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
182 /* Set one going */ |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
183 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
|
184 connect_try_next(c); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
185 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
186 if (c->sock >= 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
187 FD_SET(c->sock, writefd); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
188 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
189 /* Final failure */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
190 if (!c->errstring) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
191 c->errstring = m_strdup("unexpected failure"); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
192 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
193 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
|
194 remove_connect(c, iter); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
195 } |
1152
57d09741d46d
avoid invalidated iterator when connection fails
Matt Johnston <matt@ucc.asn.au>
parents:
1136
diff
changeset
|
196 iter = next_iter; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
197 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
198 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
199 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
200 void handle_connect_fds(fd_set *writefd) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
201 m_list_elem *iter; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
202 TRACE(("enter handle_connect_fds")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
203 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
|
204 int val; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
205 socklen_t vallen = sizeof(val); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
206 struct dropbear_progress_connection *c = iter->item; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
207 |
1053 | 208 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
|
209 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
210 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
211 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
212 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
|
213 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
214 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
|
215 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
|
216 /* 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
|
217 m_close(c->sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
218 c->sock = -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
219 } else if (val != 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
220 /* Connect failed */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
221 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
|
222 m_close(c->sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
223 c->sock = -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
224 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
225 m_free(c->errstring); |
1066 | 226 c->errstring = m_strdup(strerror(val)); |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
227 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
228 /* New connection has been established */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
229 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
|
230 remove_connect(c, iter); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
231 TRACE(("leave handle_connect_fds - success")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
232 /* Must return here - remove_connect() invalidates iter */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
233 return; |
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 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
236 TRACE(("leave handle_connect_fds - end iter")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
237 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
238 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
239 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
|
240 c->writequeue = writequeue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
241 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
242 |
1072 | 243 void packet_queue_to_iovec(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
|
244 struct Link *l; |
1034 | 245 unsigned int i; |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
246 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
247 buffer *writebuf; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
248 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
249 #ifndef IOV_MAX |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
250 #define IOV_MAX UIO_MAXIOV |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
251 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
252 |
1072 | 253 *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
|
254 |
1073
88043f9d40bd
Fix when iov queue is large
Matt Johnston <matt@ucc.asn.au>
parents:
1072
diff
changeset
|
255 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
|
256 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
257 writebuf = (buffer*)l->item; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
258 len = writebuf->len - 1 - writebuf->pos; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
259 dropbear_assert(len > 0); |
1034 | 260 TRACE2(("write_packet writev #%d type %d len %d/%d", i, writebuf->data[writebuf->len-1], |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
261 len, writebuf->len-1)) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
262 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
|
263 iov[i].iov_len = len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
264 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
265 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
266 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
267 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
|
268 buffer *writebuf; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
269 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
270 while (written > 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
271 writebuf = (buffer*)examine(queue); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
272 len = writebuf->len - 1 - writebuf->pos; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
273 if (len > written) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
274 /* partial buffer write */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
275 buf_incrpos(writebuf, written); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
276 written = 0; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
277 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
278 written -= len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
279 dequeue(queue); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
280 buf_free(writebuf); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
281 } |
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 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
284 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
285 void set_sock_nodelay(int sock) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
286 int val; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
287 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
288 /* disable nagle */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
289 val = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
290 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
|
291 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
292 |
1084
2265d7ebfdeb
separate client/server fastopen options
Matt Johnston <matt@ucc.asn.au>
parents:
1078
diff
changeset
|
293 #ifdef DROPBEAR_SERVER_TCP_FAST_OPEN |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
294 void set_listen_fast_open(int sock) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
295 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
|
296 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
|
297 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
|
298 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
299 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
300 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
301 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
302 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
303 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
|
304 |
1034 | 305 int rc; |
306 #ifdef IPTOS_LOWDELAY | |
307 int iptos_val = 0; | |
308 #endif | |
309 #ifdef SO_PRIORITY | |
310 int so_prio_val = 0; | |
311 #endif | |
312 | |
1032
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
313 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
314 /* 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
|
315 * on a client '-J' proxy pipe */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
316 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
317 /* set the TOS bit for either ipv4 or ipv6 */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
318 #ifdef IPTOS_LOWDELAY |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
319 if (prio == DROPBEAR_PRIO_LOWDELAY) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
320 iptos_val = IPTOS_LOWDELAY; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
321 } else if (prio == DROPBEAR_PRIO_BULK) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
322 iptos_val = IPTOS_THROUGHPUT; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
323 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
324 #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
325 rc = setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (void*)&iptos_val, sizeof(iptos_val)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
326 if (rc < 0 && errno != ENOTSOCK) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
327 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
|
328 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
329 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
330 rc = setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&iptos_val, sizeof(iptos_val)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
331 if (rc < 0 && errno != ENOTSOCK) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
332 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
|
333 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
334 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
335 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
336 #ifdef SO_PRIORITY |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
337 if (prio == DROPBEAR_PRIO_LOWDELAY) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
338 so_prio_val = TC_PRIO_INTERACTIVE; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
339 } else if (prio == DROPBEAR_PRIO_BULK) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
340 so_prio_val = TC_PRIO_BULK; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
341 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
342 /* linux specific, sets QoS class. see tc-prio(8) */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
343 rc = setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &so_prio_val, sizeof(so_prio_val)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
344 if (rc < 0 && errno != ENOTSOCK) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
345 dropbear_log(LOG_WARNING, "Couldn't set SO_PRIORITY (%s)", |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
346 strerror(errno)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
347 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
348 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
349 } |
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 /* Listen on address:port. |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
352 * 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
|
353 * 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
|
354 * 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
|
355 * 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
|
356 * string.*/ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
357 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
|
358 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
|
359 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
360 struct addrinfo hints, *res = NULL, *res0 = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
361 int err; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
362 unsigned int nsock; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
363 struct linger linger; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
364 int val; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
365 int sock; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
366 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
367 TRACE(("enter dropbear_listen")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
368 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
369 memset(&hints, 0, sizeof(hints)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
370 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
|
371 hints.ai_socktype = SOCK_STREAM; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
372 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
373 /* for calling getaddrinfo: |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
374 address == NULL and !AI_PASSIVE: local loopback |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
375 address == NULL and AI_PASSIVE: all interfaces |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
376 address != NULL: whatever the address says */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
377 if (!address) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
378 TRACE(("dropbear_listen: local loopback")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
379 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
380 if (address[0] == '\0') { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
381 TRACE(("dropbear_listen: all interfaces")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
382 address = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
383 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
384 hints.ai_flags = AI_PASSIVE; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
385 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
386 err = getaddrinfo(address, port, &hints, &res0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
387 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
388 if (err) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
389 if (errstring != NULL && *errstring == NULL) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
390 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
391 len = 20 + strlen(gai_strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
392 *errstring = (char*)m_malloc(len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
393 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
|
394 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
395 if (res0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
396 freeaddrinfo(res0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
397 res0 = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
398 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
399 TRACE(("leave dropbear_listen: failed resolving")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
400 return -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
401 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
402 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
403 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
404 nsock = 0; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
405 for (res = res0; res != NULL && nsock < sockcount; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
406 res = res->ai_next) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
407 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
408 /* Get a socket */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
409 socks[nsock] = socket(res->ai_family, res->ai_socktype, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
410 res->ai_protocol); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
411 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
412 sock = socks[nsock]; /* For clarity */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
413 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
414 if (sock < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
415 err = errno; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
416 TRACE(("socket() failed")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
417 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
418 } |
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 /* Various useful socket options */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
421 val = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
422 /* set to reuse, quick timeout */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
423 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
|
424 linger.l_onoff = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
425 linger.l_linger = 5; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
426 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
|
427 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
428 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
429 if (res->ai_family == AF_INET6) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
430 int on = 1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
431 if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
432 &on, sizeof(on)) == -1) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
433 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
|
434 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
435 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
436 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
437 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
438 set_sock_nodelay(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
439 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
440 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
|
441 err = errno; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
442 close(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
443 TRACE(("bind(%s) failed", port)) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
444 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
445 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
446 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
447 if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
448 err = errno; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
449 close(sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
450 TRACE(("listen() failed")) |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
451 continue; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
452 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
453 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
454 *maxfd = MAX(*maxfd, sock); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
455 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
456 nsock++; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
457 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
458 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
459 if (res0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
460 freeaddrinfo(res0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
461 res0 = NULL; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
462 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
463 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
464 if (nsock == 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
465 if (errstring != NULL && *errstring == NULL) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
466 int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
467 len = 20 + strlen(strerror(err)); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
468 *errstring = (char*)m_malloc(len); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
469 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
|
470 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
471 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
|
472 return -1; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
473 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
474 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
475 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
|
476 return nsock; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
477 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
478 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
479 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
|
480 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
|
481 { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
482 struct sockaddr_storage addr; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
483 socklen_t addrlen; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
484 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
485 if (local_host || local_port) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
486 addrlen = sizeof(addr); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
487 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
|
488 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
|
489 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
490 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
|
491 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
492 if (remote_host || remote_port) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
493 addrlen = sizeof(addr); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
494 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
|
495 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
|
496 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
497 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
|
498 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
499 } |
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 /* 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
|
502 * value is allocated with malloc() */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
503 void getaddrstring(struct sockaddr_storage* addr, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
504 char **ret_host, char **ret_port, |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
505 int host_lookup) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
506 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
507 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
|
508 unsigned int len; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
509 int ret; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
510 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
511 int flags = NI_NUMERICSERV | NI_NUMERICHOST; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
512 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
513 #ifndef DO_HOST_LOOKUP |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
514 host_lookup = 0; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
515 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
516 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
517 if (host_lookup) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
518 flags = NI_NUMERICSERV; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
519 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
520 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
521 len = sizeof(struct sockaddr_storage); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
522 /* 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
|
523 * 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
|
524 * 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
|
525 * but we'll ignore them */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
526 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
527 if (addr->ss_family == AF_INET) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
528 len = sizeof(struct sockaddr_in); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
529 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
530 #ifdef AF_INET6 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
531 if (addr->ss_family == AF_INET6) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
532 len = sizeof(struct sockaddr_in6); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
533 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
534 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
535 #endif |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
536 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
537 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
|
538 serv, sizeof(serv)-1, flags); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
539 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
540 if (ret != 0) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
541 if (host_lookup) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
542 /* 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
|
543 * 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
|
544 * to exhibit that behaviour. */ |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
545 getaddrstring(addr, ret_host, ret_port, 0); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
546 return; |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
547 } else { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
548 /* 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
|
549 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
|
550 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
551 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
552 |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
553 if (ret_host) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
554 *ret_host = m_strdup(host); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
555 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
556 if (ret_port) { |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
557 *ret_port = m_strdup(serv); |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
558 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
559 } |
0da8ba489c23
Move generic network routines to netio.c
Matt Johnston <matt@ucc.asn.au>
parents:
diff
changeset
|
560 |