void ssh_stream_fd_destroy(void *context) { SshFdStream sdata = (SshFdStream)context; /* Mark it as destroyed. */ assert(!sdata->destroyed); sdata->destroyed = TRUE; sdata->callback = NULL_FNPTR; /* Unregister the descriptors from the event loop. */ if (sdata->readfd >= 0) ssh_io_unregister_fd(sdata->readfd, sdata->keep_nonblocking); if (sdata->readfd != sdata->writefd && sdata->writefd >= 0) ssh_io_unregister_fd(sdata->writefd, sdata->keep_nonblocking); /* Close the file descriptors if appropriate. */ if (sdata->close_on_destroy) { if (sdata->readfd >= 0) close(sdata->readfd); if (sdata->readfd != sdata->writefd && sdata->writefd >= 0) close(sdata->writefd); sdata->writefd = -1; sdata->readfd = -1; } ssh_register_timeout(&sdata->destroy_timeout, 0L, 0L, ssh_stream_fd_destroy_real, sdata); }
SshStream ssh_stream_fd_wrap2(SshIOHandle readfd, SshIOHandle writefd, Boolean close_on_destroy) { SshFdStream sdata; SshStream str; sdata = ssh_malloc(sizeof(*sdata)); if (sdata == NULL) return NULL; memset(sdata, 0, sizeof(*sdata)); sdata->readfd = readfd; sdata->writefd = writefd; sdata->close_on_destroy = close_on_destroy; sdata->read_has_failed = FALSE; sdata->write_has_failed = FALSE; sdata->destroyed = FALSE; sdata->keep_nonblocking = FALSE; sdata->callback = NULL_FNPTR; if (readfd >= 0) { if (ssh_io_register_fd(readfd, ssh_stream_fd_callback, (void *)sdata) == FALSE ) { ssh_free(sdata); return NULL; } } if (readfd != writefd && writefd >= 0) { if (ssh_io_register_fd(writefd, ssh_stream_fd_callback, (void *)sdata) == FALSE ) { if (readfd >= 0) ssh_io_unregister_fd(readfd,TRUE); ssh_free(sdata); return NULL; } } str = ssh_stream_create(&ssh_stream_fd_methods, (void *)sdata); if (str == NULL) { ssh_free(sdata); if (readfd >= 0) ssh_io_unregister_fd(readfd, TRUE); if (readfd != writefd && writefd >= 0) ssh_io_unregister_fd(writefd, TRUE); return NULL; } return str; }
void ssh_stream_fd_output_eof(void *context) { SshFdStream sdata = (SshFdStream)context; assert(!sdata->destroyed); /* We don't want to get more callbacks for write. */ sdata->write_has_failed = FALSE; if (sdata->writefd >= 0) { if (sdata->writefd == sdata->readfd) { /* Note: if writefd is not a socket, this will do nothing. */ shutdown(sdata->writefd, 1); } else { /* Close the outgoing file descriptor. */ ssh_io_unregister_fd(sdata->writefd, sdata->keep_nonblocking); close(sdata->writefd); sdata->writefd = -1; } } }
void ssh_local_destroy_listener(SshLocalListener listener) { ssh_io_unregister_fd(listener->sock, FALSE); close(listener->sock); ssh_xfree(listener->path); ssh_xfree(listener); }
void ssh_stream_fd_destroy(void *context) { SshFdStream sdata = (SshFdStream)context; /* Mark it as destroyed. */ assert(!sdata->destroyed); sdata->destroyed = TRUE; sdata->callback = NULL; /* Unregister the descriptors from the event loop. */ if (sdata->readfd >= 0) ssh_io_unregister_fd(sdata->readfd, sdata->keep_nonblocking); if (sdata->readfd != sdata->writefd && sdata->writefd >= 0) ssh_io_unregister_fd(sdata->writefd, sdata->keep_nonblocking); /* Close the file descriptors if appropriate. */ if (sdata->close_on_destroy) { if (sdata->readfd >= 0) close(sdata->readfd); if (sdata->readfd != sdata->writefd && sdata->writefd >= 0) close(sdata->writefd); sdata->writefd = -1; sdata->readfd = -1; } /* Cancel any pending timeouts for us. */ ssh_cancel_timeouts(SSH_ALL_CALLBACKS, (void *)sdata); /* If this is called from a callback, delay actually freeing the context until we have returned from the callback. The destroyed flag was set above, and will be tested after the callback has returned. */ if (sdata->in_callback) return; /* Destroy the context. We first fill it with garbage to ease debugging. */ memset(sdata, 'F', sizeof(*sdata)); ssh_xfree(sdata); }
/* Close interface to tls acceleration */ void tls_accel_close(void) { #ifdef __linux__ if (registered) ssh_io_unregister_fd(device_rd_fd, FALSE); registered = FALSE; if (device_fd != -1) close(device_fd); if (device_rd_fd != -1) close(device_rd_fd); device_fd = device_rd_fd = -1; #endif /* __linux__ */ }
void ssh_local_connect_try(unsigned int events, void *context) { SshLocalConnect c = (SshLocalConnect)context; int ret; struct sockaddr_un sunaddr; /* Initialize the address to connect to. */ memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strncpy(sunaddr.sun_path, c->path, sizeof(sunaddr.sun_path)); /* Make a non-blocking connect attempt. */ ret = connect(c->sock, (struct sockaddr *)&sunaddr, AF_UNIX_SIZE(sunaddr)); if (ret >= 0 || errno == EISCONN) /* Connection is ready. */ { /* Successful connection. */ ssh_io_unregister_fd(c->sock, FALSE); (*c->callback)(ssh_stream_fd_wrap(c->sock, TRUE), c->context); ssh_xfree(c->path); ssh_xfree(c); return; } if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EALREADY) { /* Connection still in progress. */ ssh_io_set_fd_request(c->sock, SSH_IO_WRITE); return; } /* Connection failed. */ ssh_io_unregister_fd(c->sock, FALSE); close(c->sock); (*c->callback)(NULL, c->context); ssh_xfree(c->path); ssh_xfree(c); }