0x52, 0x55, 0x00, 0x00, 0x00, 0x00
};
-static const uint8_t zero_ethaddr[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-
u_int curtime;
static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
static struct in_addr dns_addr;
static u_int dns_addr_time;
+#define TIMEOUT_FAST 2 /* milliseconds */
+#define TIMEOUT_SLOW 499 /* milliseconds */
+/* for the aging of certain requests like DNS */
+#define TIMEOUT_DEFAULT 1000 /* milliseconds */
+
#ifdef _WIN32
int get_dns_addr(struct in_addr *pdns_addr)
IP_ADDR_STRING *pIPAddr;
struct in_addr tmp_addr;
- if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 1000) {
+ if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
*pdns_addr = dns_addr;
return 0;
}
if (dns_addr.s_addr != 0) {
struct stat old_stat;
- if ((curtime - dns_addr_time) < 1000) {
+ if ((curtime - dns_addr_time) < TIMEOUT_DEFAULT) {
*pdns_addr = dns_addr;
return 0;
}
return -1;
#ifdef DEBUG
- lprint("IP address of your DNS(s): ");
+ fprintf(stderr, "IP address of your DNS(s): ");
#endif
while (fgets(buff, 512, f) != NULL) {
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
}
#ifdef DEBUG
else
- lprint(", ");
+ fprintf(stderr, ", ");
#endif
if (++found > 3) {
#ifdef DEBUG
- lprint("(more)");
+ fprintf(stderr, "(more)");
#endif
break;
}
#ifdef DEBUG
else
- lprint("%s", inet_ntoa(tmp_addr));
+ fprintf(stderr, "%s", inet_ntoa(tmp_addr));
#endif
}
}
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
-void slirp_update_timeout(uint32_t *timeout)
+static void slirp_update_timeout(uint32_t *timeout)
{
- if (!QTAILQ_EMPTY(&slirp_instances)) {
- *timeout = MIN(1000, *timeout);
+ Slirp *slirp;
+ uint32_t t;
+
+ if (*timeout <= TIMEOUT_FAST) {
+ return;
}
+
+ t = MIN(1000, *timeout);
+
+ /* If we have tcp timeout with slirp, then we will fill @timeout with
+ * more precise value.
+ */
+ QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
+ if (slirp->time_fasttimo) {
+ *timeout = TIMEOUT_FAST;
+ return;
+ }
+ if (slirp->do_slowtimo) {
+ t = MIN(TIMEOUT_SLOW, t);
+ }
+ }
+ *timeout = t;
}
-void slirp_pollfds_fill(GArray *pollfds)
+void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout)
{
Slirp *slirp;
struct socket *so, *so_next;
}
}
}
+ slirp_update_timeout(timeout);
}
void slirp_pollfds_poll(GArray *pollfds, int select_error)
/*
* See if anything has timed out
*/
- if (slirp->time_fasttimo && ((curtime - slirp->time_fasttimo) >= 2)) {
+ if (slirp->time_fasttimo &&
+ ((curtime - slirp->time_fasttimo) >= TIMEOUT_FAST)) {
tcp_fasttimo(slirp);
slirp->time_fasttimo = 0;
}
- if (slirp->do_slowtimo && ((curtime - slirp->last_slowtimo) >= 499)) {
+ if (slirp->do_slowtimo &&
+ ((curtime - slirp->last_slowtimo) >= TIMEOUT_SLOW)) {
ip_slowtimo(slirp);
tcp_slowtimo(slirp);
slirp->last_slowtimo = curtime;
return 1;
}
+ if (iph->ip_dst.s_addr == 0) {
+ /* 0.0.0.0 can not be a destination address, something went wrong,
+ * avoid making it worse */
+ return 1;
+ }
if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) {
uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
struct ethhdr *reh = (struct ethhdr *)arp_req;