HTTP seek support. Various bugfixes.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-10-05 17:39:13 +02:00
parent aa6b91afe9
commit 4f71e077b9
5 changed files with 231 additions and 83 deletions

View file

@ -42,7 +42,11 @@ typedef struct http_data
grub_size_t current_line_len; grub_size_t current_line_len;
int headers_recv; int headers_recv;
int first_line_recv; int first_line_recv;
int size_recv;
grub_net_tcp_socket_t sock; grub_net_tcp_socket_t sock;
char *filename;
grub_err_t err;
char *errmsg;
} *http_data_t; } *http_data_t;
static grub_err_t static grub_err_t
@ -72,19 +76,25 @@ parse_line (http_data_t data, char *ptr, grub_size_t len)
{ {
case 200: case 200:
break; break;
case 404:
data->err = GRUB_ERR_FILE_NOT_FOUND;
data->errmsg = grub_xasprintf ("file `%s' not found", data->filename);
return GRUB_ERR_NONE;
default: default:
return grub_error (GRUB_ERR_NET_UNKNOWN_ERROR, data->err = GRUB_ERR_NET_UNKNOWN_ERROR;
"unsupported HTTP error %d: %s", data->errmsg = grub_xasprintf ("unsupported HTTP error %d: %s",
code, ptr); code, ptr);
return GRUB_ERR_NONE;
} }
data->first_line_recv = 1; data->first_line_recv = 1;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
if (grub_memcmp (ptr, "Content-Length: ", sizeof ("Content-Length: ") - 1) if (grub_memcmp (ptr, "Content-Length: ", sizeof ("Content-Length: ") - 1)
== 0) == 0 && !data->size_recv)
{ {
ptr += sizeof ("Content-Length: ") - 1; ptr += sizeof ("Content-Length: ") - 1;
data->file_size = grub_strtoull (ptr, &ptr, 10); data->file_size = grub_strtoull (ptr, &ptr, 10);
data->size_recv = 1;
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -98,10 +108,10 @@ http_err (grub_net_tcp_socket_t sock __attribute__ ((unused)),
http_data_t data = file->data; http_data_t data = file->data;
if (data->sock) if (data->sock)
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
grub_free (data);
if (data->current_line) if (data->current_line)
grub_free (data->current_line); grub_free (data->current_line);
grub_free (data);
file->device->net->eof = 1; file->device->net->eof = 1;
} }
@ -132,7 +142,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
if (!t) if (!t)
{ {
grub_netbuff_free (nb); grub_netbuff_free (nb);
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
return grub_errno; return grub_errno;
} }
@ -151,7 +161,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
data->current_line_len = 0; data->current_line_len = 0;
if (err) if (err)
{ {
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
@ -167,7 +177,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
if (!data->current_line) if (!data->current_line)
{ {
grub_netbuff_free (nb); grub_netbuff_free (nb);
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
return grub_errno; return grub_errno;
} }
data->current_line_len = (char *) nb->tail - ptr; data->current_line_len = (char *) nb->tail - ptr;
@ -178,7 +188,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
err = parse_line (data, ptr, ptr2 - ptr); err = parse_line (data, ptr, ptr2 - ptr);
if (err) if (err)
{ {
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
@ -191,7 +201,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
err = grub_netbuff_pull (nb, ptr - (char *) nb->data); err = grub_netbuff_pull (nb, ptr - (char *) nb->data);
if (err) if (err)
{ {
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
@ -203,57 +213,51 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)),
} }
static grub_err_t static grub_err_t
http_open (struct grub_file *file, const char *filename) http_establish (struct grub_file *file, grub_off_t offset, int initial)
{ {
struct grub_net_buff *nb; http_data_t data = file->data;
http_data_t data;
grub_err_t err;
grub_uint8_t *ptr; grub_uint8_t *ptr;
int i; int i;
struct grub_net_buff *nb;
data = grub_zalloc (sizeof (*data)); grub_err_t err;
if (!data)
return grub_errno;
nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE
+ sizeof ("GET ") - 1 + sizeof ("GET ") - 1
+ grub_strlen (filename) + grub_strlen (data->filename)
+ sizeof (" HTTP/1.1\r\nHost: ") - 1 + sizeof (" HTTP/1.1\r\nHost: ") - 1
+ grub_strlen (file->device->net->server) + grub_strlen (file->device->net->server)
+ sizeof ("\r\nUser-Agent: " PACKAGE_STRING + sizeof ("\r\nUser-Agent: " PACKAGE_STRING
"\r\n\r\n") - 1); "\r\n") - 1
+ sizeof ("Content-Range: bytes XXXXXXXXXXXXXXXXXXXX"
"-XXXXXXXXXXXXXXXXXXXX/"
"XXXXXXXXXXXXXXXXXXXX\r\n\r\n"));
if (!nb) if (!nb)
{ return grub_errno;
grub_free (data);
return grub_errno;
}
grub_netbuff_reserve (nb, GRUB_NET_TCP_RESERVE_SIZE); grub_netbuff_reserve (nb, GRUB_NET_TCP_RESERVE_SIZE);
ptr = nb->tail; ptr = nb->tail;
err = grub_netbuff_put (nb, sizeof ("GET ") - 1); err = grub_netbuff_put (nb, sizeof ("GET ") - 1);
if (err) if (err)
{ {
grub_free (data);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
grub_memcpy (ptr, "GET ", sizeof ("GET ") - 1); grub_memcpy (ptr, "GET ", sizeof ("GET ") - 1);
ptr = nb->tail; ptr = nb->tail;
err = grub_netbuff_put (nb, grub_strlen (filename));
err = grub_netbuff_put (nb, grub_strlen (data->filename));
if (err) if (err)
{ {
grub_free (data);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
grub_memcpy (ptr, filename, grub_strlen (filename)); grub_memcpy (ptr, data->filename, grub_strlen (data->filename));
ptr = nb->tail; ptr = nb->tail;
err = grub_netbuff_put (nb, sizeof (" HTTP/1.1\r\nHost: ") - 1); err = grub_netbuff_put (nb, sizeof (" HTTP/1.1\r\nHost: ") - 1);
if (err) if (err)
{ {
grub_free (data);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
@ -264,7 +268,6 @@ http_open (struct grub_file *file, const char *filename)
err = grub_netbuff_put (nb, grub_strlen (file->device->net->server)); err = grub_netbuff_put (nb, grub_strlen (file->device->net->server));
if (err) if (err)
{ {
grub_free (data);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
@ -273,19 +276,30 @@ http_open (struct grub_file *file, const char *filename)
ptr = nb->tail; ptr = nb->tail;
err = grub_netbuff_put (nb, err = grub_netbuff_put (nb,
sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n\r\n") sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n")
- 1); - 1);
if (err) if (err)
{ {
grub_free (data);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return err; return err;
} }
grub_memcpy (ptr, "\r\nUser-Agent: " PACKAGE_STRING "\r\n\r\n", grub_memcpy (ptr, "\r\nUser-Agent: " PACKAGE_STRING "\r\n",
sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n\r\n") - 1); sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") - 1);
if (!initial)
file->not_easily_seekable = 1; {
file->data = data; ptr = nb->tail;
grub_snprintf ((char *) ptr,
sizeof ("Content-Range: bytes XXXXXXXXXXXXXXXXXXXX-"
"XXXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXX\r\n"
"\r\n"),
"Content-Range: bytes %" PRIuGRUB_UINT64_T "-%"
PRIuGRUB_UINT64_T "/%" PRIuGRUB_UINT64_T "\r\n\r\n",
offset, data->file_size - 1, data->file_size);
grub_netbuff_put (nb, grub_strlen ((char *) ptr));
}
ptr = nb->tail;
grub_netbuff_put (nb, 2);
grub_memcpy (ptr, "\r\n", 2);
data->sock = grub_net_tcp_open (file->device->net->server, data->sock = grub_net_tcp_open (file->device->net->server,
HTTP_PORT, http_receive, HTTP_PORT, http_receive,
@ -293,7 +307,6 @@ http_open (struct grub_file *file, const char *filename)
file); file);
if (!data->sock) if (!data->sock)
{ {
grub_free (data);
grub_netbuff_free (nb); grub_netbuff_free (nb);
return grub_errno; return grub_errno;
} }
@ -303,8 +316,7 @@ http_open (struct grub_file *file, const char *filename)
err = grub_net_send_tcp_packet (data->sock, nb, 1); err = grub_net_send_tcp_packet (data->sock, nb, 1);
if (err) if (err)
{ {
grub_free (data); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
grub_net_tcp_close (data->sock);
return err; return err;
} }
@ -316,9 +328,81 @@ http_open (struct grub_file *file, const char *filename)
if (!data->headers_recv) if (!data->headers_recv)
{ {
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
if (data->err)
{
char *str = data->errmsg;
err = grub_error (data->err, "%s", str);
grub_free (str);
return data->err;
}
return grub_error (GRUB_ERR_TIMEOUT, "timeout opening http");
}
return GRUB_ERR_NONE;
}
static grub_err_t
http_seek (struct grub_file *file, grub_off_t off)
{
struct http_data *old_data, *data;
grub_err_t err;
old_data = file->data;
/* FIXME: Reuse socket? */
grub_net_tcp_close (old_data->sock, GRUB_NET_TCP_ABORT);
while (file->device->net->packs.first)
grub_net_remove_packet (file->device->net->packs.first);
data = grub_zalloc (sizeof (*data));
if (!data)
return grub_errno;
data->file_size = old_data->file_size;
data->size_recv = 1;
data->filename = old_data->filename;
if (!data->filename)
{
grub_free (data); grub_free (data);
return grub_error (GRUB_ERR_TIMEOUT, "Time out opening http."); return grub_errno;
}
grub_free (old_data);
err = http_establish (file, off, 0);
if (err)
{
grub_free (data->filename);
grub_free (data);
return err;
}
return GRUB_ERR_NONE;
}
static grub_err_t
http_open (struct grub_file *file, const char *filename)
{
grub_err_t err;
struct http_data *data;
data = grub_zalloc (sizeof (*data));
if (!data)
return grub_errno;
data->filename = grub_strdup (filename);
if (!data->filename)
{
grub_free (data);
return grub_errno;
}
file->not_easily_seekable = 0;
file->data = data;
err = http_establish (file, 0, 1);
if (err)
{
grub_free (data->filename);
grub_free (data);
return err;
} }
file->size = data->file_size; file->size = data->file_size;
@ -331,10 +415,10 @@ http_close (struct grub_file *file)
http_data_t data = file->data; http_data_t data = file->data;
if (data->sock) if (data->sock)
grub_net_tcp_close (data->sock); grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT);
grub_free (data);
if (data->current_line) if (data->current_line)
grub_free (data->current_line); grub_free (data->current_line);
grub_free (data);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -342,7 +426,8 @@ static struct grub_net_app_protocol grub_http_protocol =
{ {
.name = "http", .name = "http",
.open = http_open, .open = http_open,
.close = http_close .close = http_close,
.seek = http_seek
}; };
GRUB_MOD_INIT (http) GRUB_MOD_INIT (http)

View file

@ -815,17 +815,17 @@ grub_net_poll_cards_idle_real (void)
static grub_ssize_t static grub_ssize_t
grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len) grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
{ {
grub_net_t sock = file->device->net; grub_net_t net = file->device->net;
struct grub_net_buff *nb; struct grub_net_buff *nb;
char *ptr = buf; char *ptr = buf;
grub_size_t amount, total = 0; grub_size_t amount, total = 0;
int try = 0; int try = 0;
while (try <= 3) while (try <= 3)
{ {
while (sock->packs.first) while (net->packs.first)
{ {
try = 0; try = 0;
nb = sock->packs.first->nb; nb = net->packs.first->nb;
amount = nb->tail - nb->data; amount = nb->tail - nb->data;
if (amount > len) if (amount > len)
amount = len; amount = len;
@ -840,7 +840,7 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
if (amount == (grub_size_t) (nb->tail - nb->data)) if (amount == (grub_size_t) (nb->tail - nb->data))
{ {
grub_netbuff_free (nb); grub_netbuff_free (nb);
grub_net_remove_packet (sock->packs.first); grub_net_remove_packet (net->packs.first);
} }
else else
nb->data += amount; nb->data += amount;
@ -848,7 +848,7 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
if (!len) if (!len)
return total; return total;
} }
if (!sock->eof) if (!net->eof)
{ {
try++; try++;
grub_net_poll_cards (200); grub_net_poll_cards (200);
@ -856,39 +856,59 @@ grub_net_fs_read_real (grub_file_t file, char *buf, grub_size_t len)
else else
return total; return total;
} }
return total; grub_error (GRUB_ERR_TIMEOUT, "timeout reading '%s'", net->name);
return -1;
}
static grub_off_t
have_ahead (struct grub_file *file)
{
grub_net_t net = file->device->net;
grub_off_t ret = net->offset;
struct grub_net_packet *pack;
for (pack = net->packs.first; pack; pack = pack->next)
ret += pack->nb->tail - pack->nb->data;
return ret;
} }
static grub_err_t static grub_err_t
grub_net_seek_real (struct grub_file *file, grub_off_t offset) grub_net_seek_real (struct grub_file *file, grub_off_t offset)
{ {
grub_size_t len = offset - file->device->net->offset; if (offset == file->device->net->offset)
if (!len)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
if (file->device->net->offset > offset) if (offset > file->device->net->offset)
{ {
grub_err_t err; if (!file->device->net->protocol->seek || have_ahead (file) >= offset)
while (file->device->net->packs.first)
{ {
grub_netbuff_free (file->device->net->packs.first->nb); grub_net_fs_read_real (file, NULL,
grub_net_remove_packet (file->device->net->packs.first); offset - file->device->net->offset);
return grub_errno;
} }
file->device->net->protocol->close (file); return file->device->net->protocol->seek (file, offset);
file->device->net->packs.first = NULL;
file->device->net->packs.last = NULL;
file->device->net->offset = 0;
file->device->net->eof = 0;
err = file->device->net->protocol->open (file, file->device->net->name);
if (err)
return err;
len = offset;
} }
grub_net_fs_read_real (file, NULL, len); {
return GRUB_ERR_NONE; grub_err_t err;
if (file->device->net->protocol->seek)
return file->device->net->protocol->seek (file, offset);
while (file->device->net->packs.first)
{
grub_netbuff_free (file->device->net->packs.first->nb);
grub_net_remove_packet (file->device->net->packs.first);
}
file->device->net->protocol->close (file);
file->device->net->packs.first = NULL;
file->device->net->packs.last = NULL;
file->device->net->offset = 0;
file->device->net->eof = 0;
err = file->device->net->protocol->open (file, file->device->net->name);
if (err)
return err;
grub_net_fs_read_real (file, NULL, offset);
return grub_errno;
}
} }
static grub_ssize_t static grub_ssize_t

View file

@ -56,7 +56,8 @@ struct grub_net_tcp_socket
int in_port; int in_port;
int out_port; int out_port;
int errors; int errors;
int reseted; int they_reseted;
int i_reseted;
grub_uint32_t my_start_seq; grub_uint32_t my_start_seq;
grub_uint32_t my_cur_seq; grub_uint32_t my_cur_seq;
grub_uint32_t their_start_seq; grub_uint32_t their_start_seq;
@ -153,7 +154,7 @@ error (grub_net_tcp_socket_t sock)
{ {
struct unacked *unack, *next; struct unacked *unack, *next;
if (sock->established && sock->error_hook) if (sock->error_hook)
sock->error_hook (sock, sock->hook_data); sock->error_hook (sock, sock->hook_data);
for (unack = sock->unack_first; unack; unack = next) for (unack = sock->unack_first; unack; unack = next)
@ -217,7 +218,8 @@ tcp_send (struct grub_net_buff *nb, grub_net_tcp_socket_t socket)
} }
void void
grub_net_tcp_close (grub_net_tcp_socket_t sock) grub_net_tcp_close (grub_net_tcp_socket_t sock,
int discard_received)
{ {
struct grub_net_buff *nb_fin; struct grub_net_buff *nb_fin;
struct tcphdr *tcph_fin; struct tcphdr *tcph_fin;
@ -225,6 +227,9 @@ grub_net_tcp_close (grub_net_tcp_socket_t sock)
sock->i_closed = 1; sock->i_closed = 1;
if (discard_received != GRUB_NET_TCP_CONTINUE_RECEIVING)
sock->recv_hook = NULL;
nb_fin = grub_netbuff_alloc (sizeof (*tcph_fin) nb_fin = grub_netbuff_alloc (sizeof (*tcph_fin)
+ GRUB_NET_OUR_IPV4_HEADER_SIZE + GRUB_NET_OUR_IPV4_HEADER_SIZE
+ GRUB_NET_MAX_LINK_HEADER_SIZE); + GRUB_NET_MAX_LINK_HEADER_SIZE);
@ -254,6 +259,8 @@ grub_net_tcp_close (grub_net_tcp_socket_t sock)
tcph_fin->window = grub_cpu_to_be16 (0); tcph_fin->window = grub_cpu_to_be16 (0);
tcph_fin->urgent = 0; tcph_fin->urgent = 0;
err = tcp_send (nb_fin, sock); err = tcp_send (nb_fin, sock);
if (discard_received == GRUB_NET_TCP_ABORT)
sock->i_reseted = 1;
if (err) if (err)
{ {
grub_netbuff_free (nb_fin); grub_netbuff_free (nb_fin);
@ -264,7 +271,7 @@ grub_net_tcp_close (grub_net_tcp_socket_t sock)
} }
static void static void
ack (grub_net_tcp_socket_t sock) ack_real (grub_net_tcp_socket_t sock, int res)
{ {
struct grub_net_buff *nb_ack; struct grub_net_buff *nb_ack;
struct tcphdr *tcph_ack; struct tcphdr *tcph_ack;
@ -291,9 +298,18 @@ ack (grub_net_tcp_socket_t sock)
return; return;
} }
tcph_ack = (void *) nb_ack->data; tcph_ack = (void *) nb_ack->data;
tcph_ack->ack = grub_cpu_to_be32 (sock->their_cur_seq); if (res)
tcph_ack->flags = grub_cpu_to_be16 ((5 << 12) | TCP_ACK); {
tcph_ack->window = grub_cpu_to_be16 (sock->my_window); tcph_ack->ack = grub_cpu_to_be32 (0);
tcph_ack->flags = grub_cpu_to_be16 ((5 << 12) | TCP_RST);
tcph_ack->window = grub_cpu_to_be16 (0);
}
else
{
tcph_ack->ack = grub_cpu_to_be32 (sock->their_cur_seq);
tcph_ack->flags = grub_cpu_to_be16 ((5 << 12) | TCP_ACK);
tcph_ack->window = grub_cpu_to_be16 (sock->my_window);
}
tcph_ack->urgent = 0; tcph_ack->urgent = 0;
tcph_ack->src = grub_cpu_to_be16 (sock->in_port); tcph_ack->src = grub_cpu_to_be16 (sock->in_port);
tcph_ack->dst = grub_cpu_to_be16 (sock->out_port); tcph_ack->dst = grub_cpu_to_be16 (sock->out_port);
@ -305,6 +321,18 @@ ack (grub_net_tcp_socket_t sock)
} }
} }
static void
ack (grub_net_tcp_socket_t sock)
{
ack_real (sock, 0);
}
static void
reset (grub_net_tcp_socket_t sock)
{
ack_real (sock, 1);
}
void void
grub_net_tcp_retransmit (void) grub_net_tcp_retransmit (void)
{ {
@ -434,6 +462,7 @@ grub_net_tcp_accept (grub_net_tcp_socket_t sock,
tcph->flags = grub_cpu_to_be16 ((5 << 12) | TCP_SYN | TCP_ACK); tcph->flags = grub_cpu_to_be16 ((5 << 12) | TCP_SYN | TCP_ACK);
tcph->window = grub_cpu_to_be16 (sock->my_window); tcph->window = grub_cpu_to_be16 (sock->my_window);
tcph->urgent = 0; tcph->urgent = 0;
sock->established = 1;
tcp_socket_register (sock); tcp_socket_register (sock);
err = tcp_send (nb_ack, sock); err = tcp_send (nb_ack, sock);
if (err) if (err)
@ -555,7 +584,7 @@ grub_net_tcp_open (char *server,
{ {
grub_list_remove (GRUB_AS_LIST_P (&tcp_sockets), grub_list_remove (GRUB_AS_LIST_P (&tcp_sockets),
GRUB_AS_LIST (socket)); GRUB_AS_LIST (socket));
if (socket->reseted) if (socket->they_reseted)
grub_error (GRUB_ERR_NET_PORT_CLOSED, "port closed"); grub_error (GRUB_ERR_NET_PORT_CLOSED, "port closed");
else else
grub_error (GRUB_ERR_NET_NO_ANSWER, "no answer"); grub_error (GRUB_ERR_NET_NO_ANSWER, "no answer");
@ -693,7 +722,7 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
if (grub_be_to_cpu16 (tcph->flags) & TCP_RST) if (grub_be_to_cpu16 (tcph->flags) & TCP_RST)
{ {
sock->reseted = 1; sock->they_reseted = 1;
error (sock); error (sock);
@ -725,7 +754,7 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
grub_free (unack); grub_free (unack);
} }
sock->unack_first = unack; sock->unack_first = unack;
if (!sock->unack_last) if (!sock->unack_first)
sock->unack_last = NULL; sock->unack_last = NULL;
} }
@ -735,6 +764,12 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
grub_netbuff_free (nb); grub_netbuff_free (nb);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
if (sock->i_reseted)
{
reset (sock);
grub_netbuff_free (nb);
return GRUB_ERR_NONE;
}
err = grub_priority_queue_push (sock->pq, &nb); err = grub_priority_queue_push (sock->pq, &nb);
if (err) if (err)

View file

@ -204,6 +204,7 @@ struct grub_net_app_protocol
int (*hook) (const char *filename, int (*hook) (const char *filename,
const struct grub_dirhook_info *info)); const struct grub_dirhook_info *info));
grub_err_t (*open) (struct grub_file *file, const char *filename); grub_err_t (*open) (struct grub_file *file, const char *filename);
grub_err_t (*seek) (struct grub_file *file, grub_off_t off);
grub_err_t (*close) (struct grub_file *file); grub_err_t (*close) (struct grub_file *file);
}; };

View file

@ -53,8 +53,15 @@ grub_net_send_tcp_packet (const grub_net_tcp_socket_t socket,
struct grub_net_buff *nb, struct grub_net_buff *nb,
int push); int push);
enum
{
GRUB_NET_TCP_CONTINUE_RECEIVING,
GRUB_NET_TCP_DISCARD,
GRUB_NET_TCP_ABORT
};
void void
grub_net_tcp_close (grub_net_tcp_socket_t sock); grub_net_tcp_close (grub_net_tcp_socket_t sock, int discard_received);
grub_err_t grub_err_t
grub_net_tcp_accept (grub_net_tcp_socket_t sock, grub_net_tcp_accept (grub_net_tcp_socket_t sock,