int vsf_ftpdataio_dispose_transfer_fd(struct vsf_session* p_sess) { int dispose_ret = 1; int retval; if (p_sess->data_fd == -1) { bug("no data descriptor in vsf_ftpdataio_dispose_transfer_fd"); } vsf_sysutil_uninstall_io_handler(); if (p_sess->data_use_ssl && p_sess->ssl_slave_active) { char result; start_data_alarm(p_sess); priv_sock_send_cmd(p_sess->ssl_consumer_fd, PRIV_SOCK_DO_SSL_CLOSE); result = priv_sock_get_result(p_sess->ssl_consumer_fd); if (result != PRIV_SOCK_RESULT_OK) { dispose_ret = 0; } } else if (p_sess->p_data_ssl) { start_data_alarm(p_sess); dispose_ret = ssl_data_close(p_sess); } if (!p_sess->abor_received && !p_sess->data_timeout && dispose_ret == 1) { /* If we didn't get a failure, linger on the close() in order to get more * accurate transfer times. */ start_data_alarm(p_sess); vsf_sysutil_activate_linger(p_sess->data_fd); } /* This close() blocks because we set SO_LINGER */ retval = vsf_sysutil_close_failok(p_sess->data_fd); if (vsf_sysutil_retval_is_error(retval)) { /* Do it again without blocking. */ vsf_sysutil_deactivate_linger_failok(p_sess->data_fd); (void) vsf_sysutil_close_failok(p_sess->data_fd); } p_sess->data_fd = -1; if (tunable_data_connection_timeout > 0) { vsf_sysutil_clear_alarm(); } if (p_sess->abor_received || p_sess->data_timeout) { dispose_ret = 0; } return dispose_ret; }
static void init_data_sock_params(struct vsf_session* p_sess, int sock_fd) { if (p_sess->data_fd != -1) { bug("data descriptor still present in init_data_sock_params"); } p_sess->data_fd = sock_fd; p_sess->data_progress = 0; vsf_sysutil_activate_keepalive(sock_fd); /* And in the vague hope it might help... */ vsf_sysutil_set_iptos_throughput(sock_fd); /* Set up lingering, so that we wait for all data to transfer, and report * more accurate transfer rates. */ vsf_sysutil_activate_linger(sock_fd); /* Start the timeout monitor */ vsf_sysutil_install_io_handler(handle_io, p_sess); start_data_alarm(p_sess); }