smb: Use the connection's upload buffer
Use the connection's upload buffer instead of allocating our own send buffer.
This commit is contained in:
parent
b4433a8ba6
commit
89cce1e458
70
lib/smb.c
70
lib/smb.c
@ -252,9 +252,8 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done)
|
|||||||
/* Initialize the connection state */
|
/* Initialize the connection state */
|
||||||
memset(smbc, 0, sizeof(*smbc));
|
memset(smbc, 0, sizeof(*smbc));
|
||||||
smbc->state = SMB_CONNECTING;
|
smbc->state = SMB_CONNECTING;
|
||||||
smbc->send_buf = malloc(MAX_MESSAGE_SIZE);
|
|
||||||
smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
|
smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
|
||||||
if(!smbc->send_buf || !smbc->recv_buf)
|
if(!smbc->recv_buf)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Multiple requests are allowed with this connection */
|
/* Multiple requests are allowed with this connection */
|
||||||
@ -356,13 +355,15 @@ static void smb_format_message(struct connectdata *conn, struct smb_header *h,
|
|||||||
h->pid = smb_swap16((unsigned short) pid);
|
h->pid = smb_swap16((unsigned short) pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode smb_send(struct connectdata *conn, ssize_t len)
|
static CURLcode smb_send(struct connectdata *conn, ssize_t len,
|
||||||
|
size_t upload_size)
|
||||||
{
|
{
|
||||||
struct smb_conn *smbc = &conn->proto.smbc;
|
struct smb_conn *smbc = &conn->proto.smbc;
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
result = Curl_write(conn, FIRSTSOCKET, smbc->send_buf, len, &bytes_written);
|
result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
|
||||||
|
len, &bytes_written);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -371,6 +372,8 @@ static CURLcode smb_send(struct connectdata *conn, ssize_t len)
|
|||||||
smbc->sent = bytes_written;
|
smbc->sent = bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smbc->upload_size = upload_size;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +387,8 @@ static CURLcode smb_flush(struct connectdata *conn)
|
|||||||
if(!smbc->send_size)
|
if(!smbc->send_size)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
result = Curl_write(conn, FIRSTSOCKET, smbc->send_buf + smbc->sent,
|
result = Curl_write(conn, FIRSTSOCKET,
|
||||||
|
conn->data->state.uploadbuffer + smbc->sent,
|
||||||
len, &bytes_written);
|
len, &bytes_written);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
@ -400,12 +404,12 @@ static CURLcode smb_flush(struct connectdata *conn)
|
|||||||
static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
|
static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
|
||||||
const void *msg, size_t msg_len)
|
const void *msg, size_t msg_len)
|
||||||
{
|
{
|
||||||
struct smb_conn *smbc = &conn->proto.smbc;
|
smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
|
||||||
|
cmd, msg_len);
|
||||||
|
memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
|
||||||
|
msg, msg_len);
|
||||||
|
|
||||||
smb_format_message(conn, (struct smb_header *)smbc->send_buf, cmd, msg_len);
|
return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
|
||||||
memcpy(smbc->send_buf + sizeof(struct smb_header), msg, msg_len);
|
|
||||||
|
|
||||||
return smb_send(conn, sizeof(struct smb_header) + msg_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode smb_send_negotiate(struct connectdata *conn)
|
static CURLcode smb_send_negotiate(struct connectdata *conn)
|
||||||
@ -563,19 +567,13 @@ static CURLcode smb_send_read(struct connectdata *conn)
|
|||||||
|
|
||||||
static CURLcode smb_send_write(struct connectdata *conn)
|
static CURLcode smb_send_write(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct smb_conn *smbc = &conn->proto.smbc;
|
struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
|
||||||
struct smb_write *msg = (struct smb_write *)smbc->send_buf;
|
|
||||||
struct smb_request *req = conn->data->req.protop;
|
struct smb_request *req = conn->data->req.protop;
|
||||||
curl_off_t offset = conn->data->req.offset;
|
curl_off_t offset = conn->data->req.offset;
|
||||||
CURLcode result;
|
|
||||||
int nread;
|
|
||||||
|
|
||||||
conn->data->req.upload_fromhere = smbc->send_buf + sizeof(*msg);
|
curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
|
||||||
result = Curl_fillreadbuffer(conn, MAX_PAYLOAD_SIZE, &nread);
|
if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
|
||||||
if(result && result != CURLE_AGAIN)
|
upload_size = MAX_PAYLOAD_SIZE - 1;
|
||||||
return result;
|
|
||||||
if(!nread)
|
|
||||||
return CURLE_OK;
|
|
||||||
|
|
||||||
memset(msg, 0, sizeof(*msg));
|
memset(msg, 0, sizeof(*msg));
|
||||||
msg->word_count = SMB_WC_WRITE_ANDX;
|
msg->word_count = SMB_WC_WRITE_ANDX;
|
||||||
@ -583,13 +581,14 @@ static CURLcode smb_send_write(struct connectdata *conn)
|
|||||||
msg->fid = smb_swap16(req->fid);
|
msg->fid = smb_swap16(req->fid);
|
||||||
msg->offset = smb_swap32((unsigned int) offset);
|
msg->offset = smb_swap32((unsigned int) offset);
|
||||||
msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
|
msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
|
||||||
msg->data_length = smb_swap16((unsigned short) nread);
|
msg->data_length = smb_swap16((unsigned short) upload_size);
|
||||||
msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
|
msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
|
||||||
|
msg->byte_count = smb_swap16((unsigned short) upload_size + 1);
|
||||||
|
|
||||||
smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
|
smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
|
||||||
sizeof(*msg) - sizeof(msg->h) + nread);
|
sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
|
||||||
|
|
||||||
return smb_send(conn, sizeof(*msg) + nread);
|
return smb_send(conn, sizeof(*msg), (size_t) upload_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
||||||
@ -597,15 +596,31 @@ static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
|
|||||||
struct smb_conn *smbc = &conn->proto.smbc;
|
struct smb_conn *smbc = &conn->proto.smbc;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
/* Check if there is still data to send */
|
/* Check if there is data in the transfer buffer */
|
||||||
|
if(!smbc->send_size && smbc->upload_size) {
|
||||||
|
int nread = smbc->upload_size > BUFSIZE ? BUFSIZE :
|
||||||
|
(int) smbc->upload_size;
|
||||||
|
conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
|
||||||
|
result = Curl_fillreadbuffer(conn, nread, &nread);
|
||||||
|
if(result && result != CURLE_AGAIN)
|
||||||
|
return result;
|
||||||
|
if(!nread)
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
smbc->upload_size -= nread;
|
||||||
|
smbc->send_size = nread;
|
||||||
|
smbc->sent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there is data to send */
|
||||||
if(smbc->send_size) {
|
if(smbc->send_size) {
|
||||||
result = smb_flush(conn);
|
result = smb_flush(conn);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some data was sent, but not all */
|
/* Check if there is still data to be sent */
|
||||||
if(smbc->send_size)
|
if(smbc->send_size || smbc->upload_size)
|
||||||
return CURLE_AGAIN;
|
return CURLE_AGAIN;
|
||||||
|
|
||||||
return smb_recv_message(conn, msg);
|
return smb_recv_message(conn, msg);
|
||||||
@ -875,7 +890,6 @@ static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
|
|||||||
(void) dead;
|
(void) dead;
|
||||||
|
|
||||||
Curl_safefree(smbc->domain);
|
Curl_safefree(smbc->domain);
|
||||||
Curl_safefree(smbc->send_buf);
|
|
||||||
Curl_safefree(smbc->recv_buf);
|
Curl_safefree(smbc->recv_buf);
|
||||||
|
|
||||||
/* smb_done is not always called, so cleanup the request */
|
/* smb_done is not always called, so cleanup the request */
|
||||||
@ -897,7 +911,7 @@ static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
|
|||||||
|
|
||||||
socks[0] = conn->sock[FIRSTSOCKET];
|
socks[0] = conn->sock[FIRSTSOCKET];
|
||||||
|
|
||||||
if(smbc->send_size)
|
if(smbc->send_size || smbc->upload_size)
|
||||||
return GETSOCK_WRITESOCK(0);
|
return GETSOCK_WRITESOCK(0);
|
||||||
|
|
||||||
return GETSOCK_READSOCK(0);
|
return GETSOCK_READSOCK(0);
|
||||||
|
@ -37,8 +37,8 @@ struct smb_conn {
|
|||||||
unsigned char challenge[8];
|
unsigned char challenge[8];
|
||||||
unsigned int session_key;
|
unsigned int session_key;
|
||||||
unsigned short uid;
|
unsigned short uid;
|
||||||
char *send_buf;
|
|
||||||
char *recv_buf;
|
char *recv_buf;
|
||||||
|
size_t upload_size;
|
||||||
size_t send_size;
|
size_t send_size;
|
||||||
size_t sent;
|
size_t sent;
|
||||||
size_t got;
|
size_t got;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user