So I'm trying to understand how PuTTY is implementing SCP and have a few questions.
First, here's a copy of an older and (imho) easier to read version of PuTTY's SCP implementation:
https://github.com/Yasushi/putty/blob/4eeae4a39bc9faf539b8f819c12b1d1b9f22fc86/scp.c
Here's the function that sends data:
int scp_send_filedata(char *data, int len)
{
int bufsize = back->send(data, len);
/*
* If the network transfer is backing up - that is, the remote
* site is not accepting data as fast as we can produce it -
* then we must loop on network events until we have space in
* the buffer again.
*/
while (bufsize > MAX_SCP_BUFSIZE) {
if (!scp_process_network_event())
return 1;
bufsize = back->sendbuffer();
}
return 0;
}
Here's scp_process_network_event:
static int scp_process_network_event(void)
{
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(scp_ssh_socket, &readfds);
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return 0; /* doom */
select_result((WPARAM) scp_ssh_socket, (LPARAM) FD_READ);
return 1;
}
So scp_process_network_event does a select() system call, blocking until a write operation wouldn't block?
I'm thinking back->sendbuffer and back->send correspond to this:
https://github.com/Yasushi/putty/blob/4eeae4a39bc9faf539b8f819c12b1d1b9f22fc86/ssh.c
/*
* Called to send data down the Telnet connection.
*/
static int ssh_send(char *buf, int len)
{
if (s == NULL || ssh_protocol == NULL)
return 0;
ssh_protocol(buf, len, 0);
return ssh_sendbuffer();
}
/*
* Called to query the current amount of buffered stdin data.
*/
static int ssh_sendbuffer(void)
{
int override_value;
if (s == NULL || ssh_protocol == NULL)
return 0;
/*
* If the SSH socket itself has backed up, add the total backup
* size on that to any individual buffer on the stdin channel.
*/
override_value = 0;
if (ssh_throttled_all)
override_value = ssh_overall_bufsize;
if (ssh_version == 1) {
return override_value;
} else if (ssh_version == 2) {
if (!mainchan || mainchan->closes > 0)
return override_value;
else
return override_value + bufchain_size(&mainchan->v.v2.outbuffer);
}
return 0;
}
I'm not completely sure on that though and tbh I'm not very good at C either :(
Anyway it's not entirely clear to me what bufsize is supposed to be.
Any ideas?
Thanks!