comparison dbutil.c @ 297:79bf1023cf11 agent-client

propagate from branch 'au.asn.ucc.matt.dropbear' (head 0501e6f661b5415eb76f3b312d183c3adfbfb712) to branch 'au.asn.ucc.matt.dropbear.cli-agent' (head 01038174ec27245b51bd43a66c01ad930880f67b)
author Matt Johnston <matt@ucc.asn.au>
date Tue, 21 Mar 2006 16:20:59 +0000
parents ca7e76d981d9 044bc108b9b3
children c1e9c81d1d27
comparison
equal deleted inserted replaced
225:ca7e76d981d9 297:79bf1023cf11
108 _dropbear_log(LOG_INFO, fmtbuf, param); 108 _dropbear_log(LOG_INFO, fmtbuf, param);
109 109
110 exit(exitcode); 110 exit(exitcode);
111 } 111 }
112 112
113 void fail_assert(const char* expr, const char* file, int line) {
114 dropbear_exit("failed assertion (%s:%d): `%s'", file, line, expr);
115 }
116
113 static void generic_dropbear_log(int UNUSED(priority), const char* format, 117 static void generic_dropbear_log(int UNUSED(priority), const char* format,
114 va_list param) { 118 va_list param) {
115 119
116 char printbuf[1024]; 120 char printbuf[1024];
117 121
147 fprintf(stderr, "\n"); 151 fprintf(stderr, "\n");
148 va_end(param); 152 va_end(param);
149 } 153 }
150 #endif /* DEBUG_TRACE */ 154 #endif /* DEBUG_TRACE */
151 155
152 /* Listen on address:port. Unless address is NULL, in which case listen on 156 static void set_sock_priority(int sock) {
153 * everything. If called with address == "", we'll listen on localhost/loopback. 157
158 int val;
159
160 /* disable nagle */
161 val = 1;
162 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));
163
164 /* set the TOS bit. note that this will fail for ipv6, I can't find any
165 * equivalent. */
166 #ifdef IPTOS_LOWDELAY
167 val = IPTOS_LOWDELAY;
168 setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&val, sizeof(val));
169 #endif
170
171 #ifdef SO_PRIORITY
172 /* linux specific, sets QoS class.
173 * 6 looks to be optimal for interactive traffic (see tc-prio(8) ). */
174 val = 6;
175 setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &val, sizeof(val));
176 #endif
177
178 }
179
180 /* Listen on address:port.
181 * Special cases are address of "" listening on everything,
182 * and address of NULL listening on localhost only.
154 * Returns the number of sockets bound on success, or -1 on failure. On 183 * Returns the number of sockets bound on success, or -1 on failure. On
155 * failure, if errstring wasn't NULL, it'll be a newly malloced error 184 * failure, if errstring wasn't NULL, it'll be a newly malloced error
156 * string.*/ 185 * string.*/
157 int dropbear_listen(const char* address, const char* port, 186 int dropbear_listen(const char* address, const char* port,
158 int *socks, unsigned int sockcount, char **errstring, int *maxfd) { 187 int *socks, unsigned int sockcount, char **errstring, int *maxfd) {
168 197
169 memset(&hints, 0, sizeof(hints)); 198 memset(&hints, 0, sizeof(hints));
170 hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */ 199 hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */
171 hints.ai_socktype = SOCK_STREAM; 200 hints.ai_socktype = SOCK_STREAM;
172 201
173 if (address && address[0] == '\0') { 202 // for calling getaddrinfo:
203 // address == NULL and !AI_PASSIVE: local loopback
204 // address == NULL and AI_PASSIVE: all interfaces
205 // address != NULL: whatever the address says
206 if (!address) {
174 TRACE(("dropbear_listen: local loopback")) 207 TRACE(("dropbear_listen: local loopback"))
175 address = NULL;
176 } else { 208 } else {
177 TRACE(("dropbear_listen: not local loopback")) 209 if (address[0] == '\0') {
210 TRACE(("dropbear_listen: all interfaces"))
211 address = NULL;
212 }
178 hints.ai_flags = AI_PASSIVE; 213 hints.ai_flags = AI_PASSIVE;
179 } 214 }
180 err = getaddrinfo(address, port, &hints, &res0); 215 err = getaddrinfo(address, port, &hints, &res0);
181 216
182 if (err) { 217 if (err) {
183 if (errstring != NULL && *errstring == NULL) { 218 if (errstring != NULL && *errstring == NULL) {
184 int len; 219 int len;
185 len = 20 + strlen(gai_strerror(err)); 220 len = 20 + strlen(gai_strerror(err));
186 *errstring = (char*)m_malloc(len); 221 *errstring = (char*)m_malloc(len);
187 snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err)); 222 snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err));
223 }
224 if (res0) {
225 freeaddrinfo(res0);
226 res0 = NULL;
188 } 227 }
189 TRACE(("leave dropbear_listen: failed resolving")) 228 TRACE(("leave dropbear_listen: failed resolving"))
190 return -1; 229 return -1;
191 } 230 }
192 231
213 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); 252 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));
214 linger.l_onoff = 1; 253 linger.l_onoff = 1;
215 linger.l_linger = 5; 254 linger.l_linger = 5;
216 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger)); 255 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger));
217 256
218 /* disable nagle */ 257 set_sock_priority(sock);
219 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));
220 258
221 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { 259 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
222 err = errno; 260 err = errno;
223 close(sock); 261 close(sock);
224 TRACE(("bind(%s) failed", port)) 262 TRACE(("bind(%s) failed", port))
233 } 271 }
234 272
235 *maxfd = MAX(*maxfd, sock); 273 *maxfd = MAX(*maxfd, sock);
236 274
237 nsock++; 275 nsock++;
276 }
277
278 if (res0) {
279 freeaddrinfo(res0);
280 res0 = NULL;
238 } 281 }
239 282
240 if (nsock == 0) { 283 if (nsock == 0) {
241 if (errstring != NULL && *errstring == NULL) { 284 if (errstring != NULL && *errstring == NULL) {
242 int len; 285 int len;
341 snprintf(*errstring, len, "Error connecting: %s", strerror(err)); 384 snprintf(*errstring, len, "Error connecting: %s", strerror(err));
342 } 385 }
343 TRACE(("Error connecting: %s", strerror(err))) 386 TRACE(("Error connecting: %s", strerror(err)))
344 } else { 387 } else {
345 /* Success */ 388 /* Success */
346 /* (err is used as a dummy var here) */ 389 set_sock_priority(sock);
347 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&err, sizeof(err));
348 } 390 }
349 391
350 freeaddrinfo(res0); 392 freeaddrinfo(res0);
351 if (sock > 0 && errstring != NULL && *errstring != NULL) { 393 if (sock > 0 && errstring != NULL && *errstring != NULL) {
352 m_free(*errstring); 394 m_free(*errstring);
553 } 595 }
554 596
555 } 597 }
556 #endif 598 #endif
557 599
558 /* loop until the socket is closed (in case of EINTR) or 600 /* make sure that the socket closes */
559 * we get and error. 601 void m_close(int fd) {
560 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
561 int m_close(int fd) {
562 602
563 int val; 603 int val;
564 do { 604 do {
565 val = close(fd); 605 val = close(fd);
566 } while (val < 0 && errno == EINTR); 606 } while (val < 0 && errno == EINTR);
567 607
568 if (val == 0 || errno == EBADF) { 608 if (val < 0 && errno != EBADF) {
569 return DROPBEAR_SUCCESS; 609 /* Linux says EIO can happen */
570 } else { 610 dropbear_exit("Error closing fd %d, %s", fd, strerror(errno));
571 return DROPBEAR_FAILURE;
572 } 611 }
573 } 612 }
574 613
575 void * m_malloc(size_t size) { 614 void * m_malloc(size_t size) {
576 615