Mercurial > dropbear
comparison dbutil.c @ 293:9d110777f345 contrib-blacklist
propagate from branch 'au.asn.ucc.matt.dropbear' (head 7ad1775ed65e75dbece27fe6b65bf1a234db386a)
to branch 'au.asn.ucc.matt.dropbear.contrib.blacklist' (head 1d86a4f0a401cc68c2670d821a2f6366c37af143)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 10 Mar 2006 06:31:29 +0000 |
parents | 044bc108b9b3 |
children | 79bf1023cf11 973fccb59ea4 e17f0333c21e 28b10e93685c |
comparison
equal
deleted
inserted
replaced
247:c07de41b53d7 | 293:9d110777f345 |
---|---|
151 fprintf(stderr, "\n"); | 151 fprintf(stderr, "\n"); |
152 va_end(param); | 152 va_end(param); |
153 } | 153 } |
154 #endif /* DEBUG_TRACE */ | 154 #endif /* DEBUG_TRACE */ |
155 | 155 |
156 /* Listen on address:port. Unless address is NULL, in which case listen on | 156 static void set_sock_priority(int sock) { |
157 * 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. | |
158 * 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 |
159 * 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 |
160 * string.*/ | 185 * string.*/ |
161 int dropbear_listen(const char* address, const char* port, | 186 int dropbear_listen(const char* address, const char* port, |
162 int *socks, unsigned int sockcount, char **errstring, int *maxfd) { | 187 int *socks, unsigned int sockcount, char **errstring, int *maxfd) { |
172 | 197 |
173 memset(&hints, 0, sizeof(hints)); | 198 memset(&hints, 0, sizeof(hints)); |
174 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 */ |
175 hints.ai_socktype = SOCK_STREAM; | 200 hints.ai_socktype = SOCK_STREAM; |
176 | 201 |
177 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) { | |
178 TRACE(("dropbear_listen: local loopback")) | 207 TRACE(("dropbear_listen: local loopback")) |
179 address = NULL; | |
180 } else { | 208 } else { |
181 TRACE(("dropbear_listen: not local loopback")) | 209 if (address[0] == '\0') { |
210 TRACE(("dropbear_listen: all interfaces")) | |
211 address = NULL; | |
212 } | |
182 hints.ai_flags = AI_PASSIVE; | 213 hints.ai_flags = AI_PASSIVE; |
183 } | 214 } |
184 err = getaddrinfo(address, port, &hints, &res0); | 215 err = getaddrinfo(address, port, &hints, &res0); |
185 | 216 |
186 if (err) { | 217 if (err) { |
221 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); | 252 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); |
222 linger.l_onoff = 1; | 253 linger.l_onoff = 1; |
223 linger.l_linger = 5; | 254 linger.l_linger = 5; |
224 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger)); | 255 setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger)); |
225 | 256 |
226 /* disable nagle */ | 257 set_sock_priority(sock); |
227 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); | |
228 | 258 |
229 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { | 259 if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { |
230 err = errno; | 260 err = errno; |
231 close(sock); | 261 close(sock); |
232 TRACE(("bind(%s) failed", port)) | 262 TRACE(("bind(%s) failed", port)) |
345 snprintf(*errstring, len, "Error connecting: %s", strerror(err)); | 375 snprintf(*errstring, len, "Error connecting: %s", strerror(err)); |
346 } | 376 } |
347 TRACE(("Error connecting: %s", strerror(err))) | 377 TRACE(("Error connecting: %s", strerror(err))) |
348 } else { | 378 } else { |
349 /* Success */ | 379 /* Success */ |
350 /* (err is used as a dummy var here) */ | 380 set_sock_priority(sock); |
351 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&err, sizeof(err)); | |
352 } | 381 } |
353 | 382 |
354 freeaddrinfo(res0); | 383 freeaddrinfo(res0); |
355 if (sock > 0 && errstring != NULL && *errstring != NULL) { | 384 if (sock > 0 && errstring != NULL && *errstring != NULL) { |
356 m_free(*errstring); | 385 m_free(*errstring); |
557 } | 586 } |
558 | 587 |
559 } | 588 } |
560 #endif | 589 #endif |
561 | 590 |
562 /* loop until the socket is closed (in case of EINTR) or | 591 /* make sure that the socket closes */ |
563 * we get and error. | 592 void m_close(int fd) { |
564 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | |
565 int m_close(int fd) { | |
566 | 593 |
567 int val; | 594 int val; |
568 do { | 595 do { |
569 val = close(fd); | 596 val = close(fd); |
570 } while (val < 0 && errno == EINTR); | 597 } while (val < 0 && errno == EINTR); |
571 | 598 |
572 if (val == 0 || errno == EBADF) { | 599 if (val < 0 && errno != EBADF) { |
573 return DROPBEAR_SUCCESS; | 600 /* Linux says EIO can happen */ |
574 } else { | 601 dropbear_exit("Error closing fd %d, %s", fd, strerror(errno)); |
575 return DROPBEAR_FAILURE; | |
576 } | 602 } |
577 } | 603 } |
578 | 604 |
579 void * m_malloc(size_t size) { | 605 void * m_malloc(size_t size) { |
580 | 606 |