下面是我在本文的帮助下写的一段代码:C: can I forward port for external application with libssh?。
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; /* initialize the mutex */
struct arg_struct
{
int sockfd; /* client socket */
ssh_session session; /* ssh session */
char *rhost; /* remote where we perform forwarding */
int rport; /* ssh port */
int lport; /* local port to listen on */
};
/* forward_handler: handle the port forwarding for every thread */
void *forward_handler(void *arg)
{
char data[4060];
int rc, recvl, nwritten, nread;
ssh_channel forwarding_channel;
struct arg_struct *args = (struct arg_struct*)arg;
pthread_mutex_lock(&lock); /* lock mutex until task complete */
/* requests on the fd can return immediately with a failure status if no input, vs blocking */
if ((fcntl(args->sockfd, F_SETFL, O_NONBLOCK)) != 0)
goto exit;
/* get pointer to a newly allocated channel, NULL on error */
if ((forwarding_channel = ssh_channel_new(args->session)) == NULL) {
perror("Error");
goto exit;
}
/* open a TCP/IP forwarding channel, SSH_OK if successfull */
rc = ssh_channel_open_forward(forwarding_channel,
args->rhost, args->rport,
"127.0.0.1", args->lport);
if (rc != SSH_OK) {
perror("Error");
goto exit;
}
printf("Connected! Tunnel open (127.0.0.1:%d) -> (ssh://%s) -> (\"%s:%d\")\n",
args->lport, args->rhost, args->rhost, args->rport
);
/* while we have an open channel and channel has NOT sent an EOF response */
while(ssh_channel_is_open(forwarding_channel) && !ssh_channel_is_eof(forwarding_channel))
{
if ((recvl = recv(args->sockfd, data, sizeof(data), MSG_DONTWAIT)) < 0) /* recieve data & enable nonblocking */
if ((nread = ssh_channel_read_nonblocking(forwarding_channel, data, sizeof(data), 0)) > 0) /* do a nonblocking read on the channel */
if ((write(args->sockfd, data, nread)) < 0) /* write to socket */
{
perror("Error");
goto exit;
}
else if (!recvl) {
printf("Local client disconnected, exiting\n");
goto exit;
}
nwritten = ssh_channel_write(forwarding_channel, data, recvl); /* send to the remote host */
if (recvl != nwritten) {
perror("Error");
goto exit;
}
}
exit:
ssh_channel_free(forwarding_channel); /* free the forwarding channel */
pthread_mutex_unlock(&lock); /* unlock mutex */
close(args->sockfd); /* close socket file descriptor */
pthread_exit(NULL); /* exit thread */
}
此代码尚未经过优化和严格测试,并且tbh相当快地编写了该代码,需要对其进行检查,但是目前它作为我的POC在Linux上可以工作。当我尝试在Windows上执行相同操作时,主要在以下几行中遇到问题:
if ((fcntl(args->sockfd, F_SETFL, O_NONBLOCK)) != 0)
goto exit;
---snip---
if ((recvl = recv(args->sockfd, data, sizeof(data), MSG_DONTWAIT)) < 0) /* recieve data & enable nonblocking */
if ((nread = ssh_channel_read_nonblocking(forwarding_channel, data, sizeof(data), 0)) > 0) /* do a nonblocking read on the channel */
if ((write(args->sockfd, data, nread)) < 0)
以下是我要解决的尝试:
/* forward_handler: handle the port forwarding for every thread */
void *forward_handler(void *arg)
{
char data[4096];
unsigned long int iMode = 1;
int rc, recvl, nwritten, nread;
ssh_channel forwarding_channel;
struct arg_struct *args = (struct arg_struct*)arg;
pthread_mutex_lock(&lock); /* lock mutex until task complete */
/* requests on the fd can return immediately with a failure status if no input, vs blocking */
if ((ioctlsocket(args->sockfd, FIONBIO, &iMode)) != NO_ERROR)
goto exit;
/* get pointer to a newly allocated channel, NULL on error */
if ((forwarding_channel = ssh_channel_new(args->session)) == NULL) {
fprintf(stderr, "forward_handler: Failed to create new channel with error: %d\n", forwarding_channel);
exit(0);
}
/* open a TCP/IP forwarding channel, SSH_OK if successfull */
rc = ssh_channel_open_forward(forwarding_channel,
args->rhost, args->rport,
"127.0.0.1", args->lport);
if (rc != SSH_OK) {
fprintf(stderr, "forward_handler: Failed to open forwarding channel with error: %d\n", rc);
goto exit_and_free;
}
printf("Connected! Tunnel open (127.0.0.1:%d) -> (ssh://%s) -> (\"%s:%d\")\n",
args->lport, args->rhost, args->rhost, args->rport
);
/* while we have an open channel and channel has NOT sent an EOF response */
while(ssh_channel_is_open(forwarding_channel) && !ssh_channel_is_eof(forwarding_channel))
{
if ((recvl = recv(args->sockfd, data, sizeof(data), 0)) < 0) {
if ((nread = ssh_channel_read_nonblocking(forwarding_channel, data, sizeof(data), 0)) > 0) /* do a nonblocking read on the channel */
if ((WriteFile((HANDLE)args->sockfd, data, nread, NULL, NULL)) < 0) /* write to socket */
{
fprintf(stderr, "forward_handler: Error writing to file descriptor");
goto exit_and_free;
}
}
else if (!recvl) {
printf("Local client disconnected, exiting\n");
goto exit_and_free;
}
nwritten = ssh_channel_write(forwarding_channel, data, recvl); /* send to the remote host */
if (recvl != nwritten) {
fprintf(stderr, "forward_handler: Error writing to SSH channel\n");
goto exit_and_free;
}
}
exit_and_free:
ssh_channel_free(forwarding_channel); /* free the forwarding channel */
exit:
pthread_mutex_unlock(&lock); /* unlock mutex */
close(args->sockfd); /* close socket file descriptor */
pthread_exit(NULL); /* exit thread */
}
因为我被卡住了,所以打败了我,因为糟糕的代码:)