* include/grub/net.h (grub_net_poll_cards): New argument stop_condition.
All users updated.
* grub-core/net/arp.c (have_pending): New var.
(pending_req): Likewise.
(grub_net_arp_send_request): Fill pending_req and use have_pending as
stop indicator.
(grub_net_arp_receive): Set have_pending.
* grub-core/net/dns.c (recv_data): New field stop.
(recv_hook): Set stop.
(grub_net_dns_lookup): Init stop and use as stop condition.
* grub-core/net/http.c (http_establish): Use headers_recv as stop
condition.
* grub-core/net/net.c (grub_net_poll_cards): New argument
stop_condition. Stop when it goes true.
* grub-core/net/tcp.c (grub_net_tcp_open): Use `established' as stop
indicator.
* grub-core/net/tftp.c (tftp_open): Use `have_oack' as stop indicator.
+2012-06-09 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Stop polling as soon as we have the packet we were waiting for.
+
+ * include/grub/net.h (grub_net_poll_cards): New argument stop_condition.
+ All users updated.
+ * grub-core/net/arp.c (have_pending): New var.
+ (pending_req): Likewise.
+ (grub_net_arp_send_request): Fill pending_req and use have_pending as
+ stop indicator.
+ (grub_net_arp_receive): Set have_pending.
+ * grub-core/net/dns.c (recv_data): New field stop.
+ (recv_hook): Set stop.
+ (grub_net_dns_lookup): Init stop and use as stop condition.
+ * grub-core/net/http.c (http_establish): Use headers_recv as stop
+ condition.
+ * grub-core/net/net.c (grub_net_poll_cards): New argument
+ stop_condition. Stop when it goes true.
+ * grub-core/net/tcp.c (grub_net_tcp_open): Use `established' as stop
+ indicator.
+ * grub-core/net/tftp.c (tftp_open): Use `have_oack' as stop indicator.
+
2012-06-09 Vladimir Serbinenko <phcoder@gmail.com>
Keep TX and RX buffers on EFI rather than always allocate new ones.
grub_uint16_t op;
} __attribute__ ((packed));
+static int have_pending;
+static grub_uint32_t pending_req;
grub_err_t
grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
{
if (grub_net_link_layer_resolve_check (inf, proto_addr))
return GRUB_ERR_NONE;
- grub_net_poll_cards (GRUB_NET_INTERVAL);
+ pending_req = proto_addr->ipv4;
+ have_pending = 0;
+ grub_net_poll_cards (GRUB_NET_INTERVAL, &have_pending);
if (grub_net_link_layer_resolve_check (inf, proto_addr))
return GRUB_ERR_NONE;
nb.data = nbd;
target_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
grub_memcpy (&sender_addr.ipv4, sender_protocol_address, 4);
grub_memcpy (&target_addr.ipv4, target_protocol_address, 4);
+ if (grub_memcmp (sender_protocol_address, &pending_req, 4) == 0)
+ have_pending = 1;
}
else
return GRUB_ERR_NONE;
}
if (!done)
break;
- grub_net_poll_cards (interval);
+ grub_net_poll_cards (interval, 0);
}
err = GRUB_ERR_NONE;
int dns_err;
char *name;
const char *oname;
+ int stop;
};
static inline int
grub_memcpy (&(*data->addresses)[*data->naddresses].ipv4,
ptr, 4);
(*data->naddresses)++;
+ data->stop = 1;
break;
case DNS_CLASS_AAAA:
if (length != 16)
grub_memcpy (&(*data->addresses)[*data->naddresses].ipv6,
ptr, 16);
(*data->naddresses)++;
+ data->stop = 1;
break;
case DNS_CLASS_CNAME:
if (!(redirect_cnt & (redirect_cnt - 1)))
static grub_uint16_t id = 1;
grub_err_t err = GRUB_ERR_NONE;
struct recv_data data = {naddresses, addresses, cache,
- grub_cpu_to_be16 (id++), 0, 0, name};
+ grub_cpu_to_be16 (id++), 0, 0, name, 0};
grub_uint8_t *nbd;
int have_server = 0;
if (*data.naddresses)
goto out;
}
- grub_net_poll_cards (200);
+ grub_net_poll_cards (200, &data.stop);
}
out:
grub_free (data.name);
for (i = 0; !data->headers_recv && i < 100; i++)
{
grub_net_tcp_retransmit ();
- grub_net_poll_cards (300);
+ grub_net_poll_cards (300, &data->headers_recv);
}
if (!data->headers_recv)
{
if (grub_net_link_layer_resolve_check (inf, proto_addr))
break;
- grub_net_poll_cards (GRUB_NET_INTERVAL);
+ grub_net_poll_cards (GRUB_NET_INTERVAL, 0);
if (grub_net_link_layer_resolve_check (inf, proto_addr))
break;
nb->data = nbd;
}
if (done)
break;
- grub_net_poll_cards (interval);
+ grub_net_poll_cards (interval, 0);
}
err = GRUB_ERR_NONE;
}
void
-grub_net_poll_cards (unsigned time)
+grub_net_poll_cards (unsigned time, int *stop_condition)
{
struct grub_net_card *card;
grub_uint64_t start_time;
- FOR_NET_CARDS (card)
- {
- start_time = grub_get_time_ms ();
- while ((grub_get_time_ms () - start_time) < time)
- receive_packets (card);
- }
+ start_time = grub_get_time_ms ();
+ while ((grub_get_time_ms () - start_time) < time
+ && (!stop_condition || !*stop_condition))
+ FOR_NET_CARDS (card)
+ receive_packets (card);
grub_net_tcp_retransmit ();
}
if (!net->eof)
{
try++;
- grub_net_poll_cards (GRUB_NET_INTERVAL);
+ grub_net_poll_cards (GRUB_NET_INTERVAL, &net->eof);
}
else
return total;
}
for (j = 0; (j < TCP_SYN_RETRANSMISSION_TIMEOUT / 50
&& !socket->established); j++)
- grub_net_poll_cards (50);
+ grub_net_poll_cards (50, &socket->established);
if (socket->established)
break;
}
destroy_pq (data);
return err;
}
- grub_net_poll_cards (GRUB_NET_INTERVAL);
+ grub_net_poll_cards (GRUB_NET_INTERVAL, &data->have_oack);
if (data->have_oack)
break;
}
grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str);
void
-grub_net_poll_cards (unsigned time);
+grub_net_poll_cards (unsigned time, int *stop_condition);
void grub_bootp_init (void);
void grub_bootp_fini (void);