- djm@cvs.openbsd.org 2002/02/12 12:44:46
[sftp-client.c] Let overlapped upload path handle servers which reorder ACKs. This may be permitted by the protocol spec; ok markus@
This commit is contained in:
parent
16a133339a
commit
5873dfd829
|
@ -20,6 +20,10 @@
|
||||||
[sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c]
|
[sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c]
|
||||||
Perform multiple overlapping read/write requests in file transfer. Mostly
|
Perform multiple overlapping read/write requests in file transfer. Mostly
|
||||||
done by Tobias Ringstrom <tori@ringstrom.mine.nu>; ok markus@
|
done by Tobias Ringstrom <tori@ringstrom.mine.nu>; ok markus@
|
||||||
|
- djm@cvs.openbsd.org 2002/02/12 12:44:46
|
||||||
|
[sftp-client.c]
|
||||||
|
Let overlapped upload path handle servers which reorder ACKs. This may be
|
||||||
|
permitted by the protocol spec; ok markus@
|
||||||
|
|
||||||
20020210
|
20020210
|
||||||
- (djm) OpenBSD CVS Sync
|
- (djm) OpenBSD CVS Sync
|
||||||
|
@ -7567,4 +7571,4 @@
|
||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.1844 2002/02/13 03:03:56 djm Exp $
|
$Id: ChangeLog,v 1.1845 2002/02/13 03:04:37 djm Exp $
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
/* XXX: copy between two remote sites */
|
/* XXX: copy between two remote sites */
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sftp-client.c,v 1.21 2002/02/12 12:32:27 djm Exp $");
|
RCSID("$OpenBSD: sftp-client.c,v 1.22 2002/02/12 12:44:46 djm Exp $");
|
||||||
|
|
||||||
#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
|
#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
@ -905,7 +905,7 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
|
||||||
int pflag, size_t buflen, int num_requests)
|
int pflag, size_t buflen, int num_requests)
|
||||||
{
|
{
|
||||||
int local_fd, status;
|
int local_fd, status;
|
||||||
u_int handle_len, id;
|
u_int handle_len, id, type;
|
||||||
u_int64_t offset;
|
u_int64_t offset;
|
||||||
char *handle, *data;
|
char *handle, *data;
|
||||||
Buffer msg;
|
Buffer msg;
|
||||||
|
@ -913,6 +913,16 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
|
||||||
Attrib a;
|
Attrib a;
|
||||||
u_int32_t startid;
|
u_int32_t startid;
|
||||||
u_int32_t ackid;
|
u_int32_t ackid;
|
||||||
|
struct outstanding_ack {
|
||||||
|
u_int id;
|
||||||
|
u_int len;
|
||||||
|
u_int64_t offset;
|
||||||
|
TAILQ_ENTRY(outstanding_ack) tq;
|
||||||
|
};
|
||||||
|
TAILQ_HEAD(ackhead, outstanding_ack) acks;
|
||||||
|
struct outstanding_ack *ack;
|
||||||
|
|
||||||
|
TAILQ_INIT(&acks);
|
||||||
|
|
||||||
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
|
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
|
||||||
error("Couldn't open local file \"%s\" for reading: %s",
|
error("Couldn't open local file \"%s\" for reading: %s",
|
||||||
|
@ -975,21 +985,49 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
|
ack = xmalloc(sizeof(*ack));
|
||||||
|
ack->id = ++id;
|
||||||
|
ack->offset = offset;
|
||||||
|
ack->len = len;
|
||||||
|
TAILQ_INSERT_TAIL(&acks, ack, tq);
|
||||||
|
|
||||||
buffer_clear(&msg);
|
buffer_clear(&msg);
|
||||||
buffer_put_char(&msg, SSH2_FXP_WRITE);
|
buffer_put_char(&msg, SSH2_FXP_WRITE);
|
||||||
buffer_put_int(&msg, ++id);
|
buffer_put_int(&msg, ack->id);
|
||||||
buffer_put_string(&msg, handle, handle_len);
|
buffer_put_string(&msg, handle, handle_len);
|
||||||
buffer_put_int64(&msg, offset);
|
buffer_put_int64(&msg, offset);
|
||||||
buffer_put_string(&msg, data, len);
|
buffer_put_string(&msg, data, len);
|
||||||
send_msg(fd_out, &msg);
|
send_msg(fd_out, &msg);
|
||||||
debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
|
debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
|
||||||
id, (u_int64_t)offset, len);
|
id, (u_int64_t)offset, len);
|
||||||
} else if ( id < ackid )
|
} else if (TAILQ_FIRST(&acks) == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (id == startid || len == 0 ||
|
if (ack == NULL)
|
||||||
id - ackid >= num_requests) {
|
fatal("Unexpected ACK %u", id);
|
||||||
status = get_status(fd_in, ackid);
|
|
||||||
|
if (id == startid || len == 0 || id - ackid >= num_requests) {
|
||||||
|
buffer_clear(&msg);
|
||||||
|
get_msg(fd_in, &msg);
|
||||||
|
type = buffer_get_char(&msg);
|
||||||
|
id = buffer_get_int(&msg);
|
||||||
|
|
||||||
|
if (type != SSH2_FXP_STATUS)
|
||||||
|
fatal("Expected SSH2_FXP_STATUS(%d) packet, "
|
||||||
|
"got %d", SSH2_FXP_STATUS, type);
|
||||||
|
|
||||||
|
status = buffer_get_int(&msg);
|
||||||
|
debug3("SSH2_FXP_STATUS %d", status);
|
||||||
|
|
||||||
|
/* Find the request in our queue */
|
||||||
|
for(ack = TAILQ_FIRST(&acks);
|
||||||
|
ack != NULL && ack->id != id;
|
||||||
|
ack = TAILQ_NEXT(ack, tq))
|
||||||
|
;
|
||||||
|
if (ack == NULL)
|
||||||
|
fatal("Can't find request for ID %d", id);
|
||||||
|
TAILQ_REMOVE(&acks, ack, tq);
|
||||||
|
|
||||||
if (status != SSH2_FX_OK) {
|
if (status != SSH2_FX_OK) {
|
||||||
error("Couldn't write to remote file \"%s\": %s",
|
error("Couldn't write to remote file \"%s\": %s",
|
||||||
remote_path, fx2txt(status));
|
remote_path, fx2txt(status));
|
||||||
|
@ -997,9 +1035,10 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
|
||||||
close(local_fd);
|
close(local_fd);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
debug3("In write loop, got %d offset %llu", len,
|
debug3("In write loop, ack for %u %d bytes at %llu",
|
||||||
(u_int64_t)offset);
|
ack->id, ack->len, ack->offset);
|
||||||
++ackid;
|
++ackid;
|
||||||
|
free(ack);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += len;
|
offset += len;
|
||||||
|
|
Loading…
Reference in New Issue