Skip to content

Commit

Permalink
Use non-blocking connect
Browse files Browse the repository at this point in the history
  • Loading branch information
mtheall committed Jun 20, 2016
1 parent 540a73c commit 81ec2ea
Showing 1 changed file with 64 additions and 72 deletions.
136 changes: 64 additions & 72 deletions source/ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,25 +1042,33 @@ ftp_session_connect(ftp_session_t *session)
return -1;
}

/* set socket to non-blocking */
rc = ftp_set_socket_nonblocking(session->data_fd);
if(rc != 0)
return -1;

/* connect to peer */
rc = connect(session->data_fd, (struct sockaddr*)&session->peer_addr,
sizeof(session->peer_addr));
if(rc != 0)
{
console_print(RED "connect: %d %s\n" RESET, errno, strerror(errno));
ftp_closesocket(session->data_fd, false);
session->data_fd = -1;
return -1;
if(errno != EINPROGRESS)
{
console_print(RED "connect: %d %s\n" RESET, errno, strerror(errno));
ftp_closesocket(session->data_fd, false);
session->data_fd = -1;
return -1;
}
}
else
{
console_print(CYAN "connected to %s:%u\n" RESET,
inet_ntoa(session->peer_addr.sin_addr),
ntohs(session->peer_addr.sin_port));

/* set socket to non-blocking */
rc = ftp_set_socket_nonblocking(session->data_fd);
if(rc != 0)
return -1;

console_print(CYAN "connected to %s:%u\n" RESET,
inet_ntoa(session->peer_addr.sin_addr),
ntohs(session->peer_addr.sin_port));
ftp_session_set_state(session, DATA_TRANSFER_STATE, CLOSE_PASV);
ftp_send_response(session, 150, "Ready\r\n");
}

return 0;
}
Expand Down Expand Up @@ -1312,9 +1320,18 @@ ftp_session_poll(ftp_session_t *session)
break;

case DATA_CONNECT_STATE:
/* we are waiting for a PASV connection */
pollinfo[1].fd = session->pasv_fd;
pollinfo[1].events = POLLIN;
if(session->flags & SESSION_PASV)
{
/* we are waiting for a PASV connection */
pollinfo[1].fd = session->pasv_fd;
pollinfo[1].events = POLLIN;
}
else
{
/* we are waiting to complete a PORT connection */
pollinfo[1].fd = session->data_fd;
pollinfo[1].events = POLLOUT;
}
pollinfo[1].revents = 0;
nfds = 2;
break;
Expand Down Expand Up @@ -1378,6 +1395,16 @@ ftp_session_poll(ftp_session_t *session)
if(ftp_session_accept(session) != 0)
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
}
else if(pollinfo[1].revents & POLLOUT)
{

console_print(CYAN "connected to %s:%u\n" RESET,
inet_ntoa(session->peer_addr.sin_addr),
ntohs(session->peer_addr.sin_port));

ftp_session_set_state(session, DATA_TRANSFER_STATE, CLOSE_PASV);
ftp_send_response(session, 150, "Ready\r\n");
}
break;

case DATA_TRANSFER_STATE:
Expand Down Expand Up @@ -2228,38 +2255,22 @@ ftp_xfer_file(ftp_session_t *session,
return ftp_send_response(session, 450, "failed to open file\r\n");
}

if(session->flags & SESSION_PORT)
if(session->flags & (SESSION_PORT|SESSION_PASV))
{
/* connect to the client */
ftp_session_set_state(session, DATA_TRANSFER_STATE, CLOSE_PASV);
rc = ftp_session_connect(session);
if(rc != 0)
{
/* error connecting */
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
return ftp_send_response(session, 425, "can't open data connection\r\n");
}
ftp_session_set_state(session, DATA_CONNECT_STATE, CLOSE_DATA);

/* set up the transfer */
session->flags &= ~(SESSION_RECV|SESSION_SEND);
if(mode == XFER_FILE_RETR)
{
session->flags |= SESSION_SEND;
session->transfer = retrieve_transfer;
}
else
if(session->flags & SESSION_PORT)
{
session->flags |= SESSION_RECV;
session->transfer = store_transfer;
/* setup connection */
rc = ftp_session_connect(session);
if(rc != 0)
{
/* error connecting */
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
return ftp_send_response(session, 425, "can't open data connection\r\n");
}
}

session->bufferpos = 0;
session->buffersize = 0;

return ftp_send_response(session, 150, "Ready\r\n");
}
else if(session->flags & SESSION_PASV)
{
/* set up the transfer */
session->flags &= ~(SESSION_RECV|SESSION_SEND);
if(mode == XFER_FILE_RETR)
Expand All @@ -2276,7 +2287,6 @@ ftp_xfer_file(ftp_session_t *session,
session->bufferpos = 0;
session->buffersize = 0;

ftp_session_set_state(session, DATA_CONNECT_STATE, CLOSE_DATA);
return 0;
}

Expand Down Expand Up @@ -2418,40 +2428,22 @@ ftp_xfer_dir(ftp_session_t *session,
strcpy(session->lwd, session->cwd);
}

if(session->flags & SESSION_PORT)
if(session->flags & (SESSION_PORT|SESSION_PASV))
{
/* connect to the client */
ftp_session_set_state(session, DATA_TRANSFER_STATE, CLOSE_PASV);
rc = ftp_session_connect(session);
if(rc != 0)
{
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
return ftp_send_response(session, 425, "can't open data connection\r\n");
}
ftp_session_set_state(session, DATA_CONNECT_STATE, CLOSE_DATA);

/* set up the transfer */
if(mode == XFER_DIR_NLST)
session->flags |= SESSION_NLST;
else if(mode != XFER_DIR_LIST)
if(session->flags & SESSION_PORT)
{
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
return ftp_send_response(session, 503, "Bad sequence of commands\r\n");
}

return ftp_send_response(session, 150, "Ready\r\n");
}
else if(session->flags & SESSION_PASV)
{
/* set up the transfer */
if(mode == XFER_DIR_NLST)
session->flags |= SESSION_NLST;
else if(mode != XFER_DIR_LIST)
{
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
return ftp_send_response(session, 503, "Bad sequence of commands\r\n");
/* setup connection */
rc = ftp_session_connect(session);
if(rc != 0)
{
/* error connecting */
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
return ftp_send_response(session, 425, "can't open data connection\r\n");
}
}

ftp_session_set_state(session, DATA_CONNECT_STATE, CLOSE_DATA);
return 0;
}
else if(mode == XFER_DIR_STAT)
Expand Down

0 comments on commit 81ec2ea

Please sign in to comment.