static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t session_wrap, const void* buffer, size_t size) { issl_session* session = reinterpret_cast<issl_session*>(session_wrap); if (session->socket->GetEventMask() & FD_WRITE_WILL_BLOCK) { #ifdef _WIN32 gnutls_transport_set_errno(session->sess, EAGAIN); #else errno = EAGAIN; #endif return -1; } int rv = ServerInstance->SE->Send(session->socket, reinterpret_cast<const char *>(buffer), size, 0); #ifdef _WIN32 if (rv < 0) { /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError() * and then set errno appropriately. * The gnutls library may also have a different errno variable than us, see * gnutls_transport_set_errno(3). */ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); } #endif if (rv < (int)size) ServerInstance->SE->ChangeEventMask(session->socket, FD_WRITE_WILL_BLOCK); return rv; }
static ssize_t gnutls_pull_wrapper(gnutls_transport_ptr_t session_wrap, void* buffer, size_t size) { StreamSocket* sock = reinterpret_cast<StreamSocket*>(session_wrap); #ifdef _WIN32 GnuTLSIOHook* session = static_cast<GnuTLSIOHook*>(sock->GetIOHook()); #endif if (sock->GetEventMask() & FD_READ_WILL_BLOCK) { #ifdef _WIN32 gnutls_transport_set_errno(session->sess, EAGAIN); #else errno = EAGAIN; #endif return -1; } int rv = SocketEngine::Recv(sock, reinterpret_cast<char *>(buffer), size, 0); #ifdef _WIN32 if (rv < 0) { /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError() * and then set errno appropriately. * The gnutls library may also have a different errno variable than us, see * gnutls_transport_set_errno(3). */ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); } #endif if (rv < (int)size) SocketEngine::ChangeEventMask(sock, FD_READ_WILL_BLOCK); return rv; }
ssize_t CTlsSocket::PushFunction(const void* data, size_t len) { if (!m_canWriteToSocket) { gnutls_transport_set_errno(m_session, EAGAIN); return -1; } if (!m_pSocketBackend) { gnutls_transport_set_errno(m_session, 0); return -1; } m_pSocketBackend->Write(data, len); if (m_pSocketBackend->Error()) { const int error = m_pSocketBackend->LastError(); if (error == wxSOCKET_WOULDBLOCK) { m_canWriteToSocket = false; gnutls_transport_set_errno(m_session, EAGAIN); return -1; } gnutls_transport_set_errno(m_session, 0); return -1; } return m_pSocketBackend->LastCount(); }
static ssize_t VectorPush(gnutls_transport_ptr_t transportptr, const giovec_t* iov, int iovcnt) { StreamSocket* sock = reinterpret_cast<StreamSocket*>(transportptr); #ifdef _WIN32 GnuTLSIOHook* session = static_cast<GnuTLSIOHook*>(sock->GetIOHook()); #endif if (sock->GetEventMask() & FD_WRITE_WILL_BLOCK) { #ifdef _WIN32 gnutls_transport_set_errno(session->sess, EAGAIN); #else errno = EAGAIN; #endif return -1; } // Cast the giovec_t to iovec not to IOVector so the correct function is called on Windows int ret = SocketEngine::WriteV(sock, reinterpret_cast<const iovec*>(iov), iovcnt); #ifdef _WIN32 // See the function above for more info about the usage of gnutls_transport_set_errno() on Windows if (ret < 0) gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); #endif int size = 0; for (int i = 0; i < iovcnt; i++) size += iov[i].iov_len; if (ret < size) SocketEngine::ChangeEventMask(sock, FD_WRITE_WILL_BLOCK); return ret; }
static void WSAtoTLSErrno(gnutls_session_t* session) { switch(WSAGetLastError()) { #if (GNUTLS_VERSION_NUMBER >= 0x029901) case WSAEWOULDBLOCK: gnutls_transport_set_errno(session, EAGAIN); break; case WSAEINTR: gnutls_transport_set_errno(session, EINTR); break; default: gnutls_transport_set_errno(session, EIO); break; #else case WSAEWOULDBLOCK: gnutls_transport_set_global_errno(EAGAIN); break; case WSAEINTR: gnutls_transport_set_global_errno(EINTR); break; default: gnutls_transport_set_global_errno(EIO); break; #endif } }
ssize_t CTlsSocket::PullFunction(void* data, size_t len) { #if TLSDEBUG m_pOwner->LogMessage(Debug_Debug, _T("CTlsSocket::PullFunction(%x, %d)"), data, len); #endif if (!m_pSocketBackend) { gnutls_transport_set_errno(m_session, 0); return -1; } if (m_socketClosed) return 0; if (!m_canReadFromSocket) { gnutls_transport_set_errno(m_session, EAGAIN); return -1; } int error; int read = m_pSocketBackend->Read(data, len, error); if (read < 0) { if (error == EAGAIN) { m_canReadFromSocket = false; if (m_canCheckCloseSocket && !m_pSocketBackend->IsWaiting(CRateLimiter::inbound)) { CSocketEvent *evt = new CSocketEvent(this, m_pSocketBackend, CSocketEvent::close); CSocketEventDispatcher::Get().SendEvent(evt); } } gnutls_transport_set_errno(m_session, error); return -1; } if (m_canCheckCloseSocket) { CSocketEvent *evt = new CSocketEvent(this, m_pSocketBackend, CSocketEvent::close); CSocketEventDispatcher::Get().SendEvent(evt); } if (!read) m_socket_eof = true; #if TLSDEBUG m_pOwner->LogMessage(Debug_Debug, _T(" returning %d"), read); #endif return read; }
ssize_t CTlsSocket::PullFunction(void* data, size_t len) { #if TLSDEBUG m_pOwner->LogMessage(MessageType::Debug_Debug, _T("CTlsSocket::PullFunction(%d)"), (int)len); #endif if (!m_pSocketBackend) { gnutls_transport_set_errno(m_session, 0); return -1; } if (m_socketClosed) return 0; if (!m_canReadFromSocket) { gnutls_transport_set_errno(m_session, EAGAIN); return -1; } int error; int read = m_pSocketBackend->Read(data, len, error); if (read < 0) { m_canReadFromSocket = false; if (error == EAGAIN) { if (m_canCheckCloseSocket && !m_pSocketBackend->IsWaiting(CRateLimiter::inbound)) { send_event<CSocketEvent>(m_pSocketBackend, SocketEventType::close, 0); } } else { m_socket_error = error; } gnutls_transport_set_errno(m_session, error); #if TLSDEBUG m_pOwner->LogMessage(MessageType::Debug_Debug, _T(" returning -1 due to %d"), error); #endif return -1; } if (m_canCheckCloseSocket) { send_event<CSocketEvent>(m_pSocketBackend, SocketEventType::close, 0); } if (!read) { m_socket_eof = true; } #if TLSDEBUG m_pOwner->LogMessage(MessageType::Debug_Debug, _T(" returning %d"), read); #endif return read; }
ssize_t CTlsSocket::PullFunction(void* data, size_t len) { if (!m_pSocketBackend) { gnutls_transport_set_errno(m_session, 0); return -1; } if (m_socketClosed) return 0; if (!m_canReadFromSocket) { gnutls_transport_set_errno(m_session, EAGAIN); return -1; } m_canReadFromSocket = false; m_pSocketBackend->Read(data, len); if (m_pSocketBackend->Error()) { if (m_pSocketBackend->LastError() == wxSOCKET_WOULDBLOCK) { if (m_canCheckCloseSocket) { wxSocketEvent evt(m_pSocketBackend->GetId()); evt.m_event = wxSOCKET_LOST; wxPostEvent(this, evt); } gnutls_transport_set_errno(m_session, EAGAIN); return -1; } gnutls_transport_set_errno(m_session, 0); return -1; } if (m_canCheckCloseSocket) { wxSocketEvent evt(m_pSocketBackend->GetId()); evt.m_event = wxSOCKET_LOST; wxPostEvent(this, evt); } return m_pSocketBackend->LastCount(); }
static ssize_t pull_func (gnutls_transport_ptr_t p, void *data, size_t size) { priv_data_st *priv = p; struct sockaddr_in cli_addr; socklen_t cli_addr_size; char buffer[64]; int ret; cli_addr_size = sizeof (cli_addr); ret = recvfrom (priv->fd, data, size, 0, (struct sockaddr *) &cli_addr, &cli_addr_size); if (ret == -1) return ret; if (cli_addr_size == priv->cli_addr_size && memcmp (&cli_addr, priv->cli_addr, sizeof (cli_addr)) == 0) return ret; printf ("Denied connection from %s\n", human_addr ((struct sockaddr *) &cli_addr, sizeof (cli_addr), buffer, sizeof (buffer))); gnutls_transport_set_errno (priv->session, EAGAIN); return -1; }
static gssize ekg_gnutls_pull(gnutls_transport_ptr_t connptr, gpointer buf, gsize len) { struct ekg_gnutls_connection *conn = connptr; GBufferedInputStream *s = G_BUFFERED_INPUT_STREAM(conn->connection->instream); gsize avail_bytes = g_buffered_input_stream_get_available(s); /* XXX: EOF? */ g_assert(len > 0); if (avail_bytes == 0) { if (conn->connection_error) return 0; /* EOF */ gnutls_transport_set_errno(conn->session, EAGAIN); return -1; } else { GError *err = NULL; gssize ret = g_input_stream_read( G_INPUT_STREAM(s), buf, MIN(avail_bytes, len), NULL, &err); if (ret == -1) { debug_error("ekg_gnutls_pull() failed: %s\n", err->message); g_error_free(err); } return ret; } g_assert_not_reached(); }
ssize_t TLSSocket_GnuTLS::gnutlsPullFunc( gnutls_transport_ptr_t trspt, void* data, size_t len ) { TLSSocket_GnuTLS* sok = reinterpret_cast <TLSSocket_GnuTLS*>(trspt); try { const ssize_t n = static_cast <ssize_t>( sok->m_wrapped->receiveRaw(reinterpret_cast <byte_t*>(data), len) ); if (n == 0) { gnutls_transport_set_errno(*sok->m_session->m_gnutlsSession, EAGAIN); sok->m_errno = EAGAIN; return -1; } return n; } catch (exception& e) { // Workaround for non-portable behaviour when throwing C++ exceptions // from C functions (GNU TLS) sok->m_ex = e.clone(); return -1; } }
ssize_t SslSocket::readInternal(void *buffer, size_t length) { qDebug() << "readInternal, length" << length << ", available" << d->socket->bytesAvailable(); if (d->socket->bytesAvailable() < qint64(length)) { gnutls_transport_set_errno(d->session, EAGAIN); return -1; } return d->socket->read(static_cast<char *>(buffer), length); }
ssize_t CTlsSocket::PushFunction(const void* data, size_t len) { #if TLSDEBUG m_pOwner->LogMessage(Debug_Debug, _T("CTlsSocket::PushFunction(%x, %d)"), data, len); #endif if (!m_canWriteToSocket) { gnutls_transport_set_errno(m_session, EAGAIN); return -1; } if (!m_pSocketBackend) { gnutls_transport_set_errno(m_session, 0); return -1; } int error; int written = m_pSocketBackend->Write(data, len, error); if (written < 0) { if (error == EAGAIN) { m_canWriteToSocket = false; gnutls_transport_set_errno(m_session, EAGAIN); return -1; } gnutls_transport_set_errno(m_session, 0); return -1; } #if TLSDEBUG m_pOwner->LogMessage(Debug_Debug, _T(" returning %d"), written); #endif return written; }
static ssize_t client_push_300 (gnutls_transport_ptr_t tr, const void *data, size_t len) { size_t newlen; if (len > 300) { gnutls_transport_set_errno ((gnutls_session_t)tr, EMSGSIZE); return -1; } len = min(len, sizeof(to_server)-to_server_len); newlen = to_server_len + len; memcpy (to_server + to_server_len, data, len); to_server_len = newlen; #ifdef EAGAIN_DEBUG fprintf(stderr, "eagain: pushed %d bytes to server (avail: %d)\n", (int)len, (int)to_server_len); #endif return len; }
static inline void tls_set_errno(struct gnutella_socket *s, int errnum) { gnutls_transport_set_errno(tls_socket_get_session(s), errnum); }
ssize_t mgs_transport_read(gnutls_transport_ptr_t ptr, void *buffer, size_t len) { mgs_handle_t *ctxt = ptr; apr_status_t rc; apr_size_t in = len; apr_read_type_e block = ctxt->input_block; ctxt->input_rc = APR_SUCCESS; /* If Len = 0, we don't do anything. */ if (!len || buffer == NULL) { return 0; } if (!ctxt->input_bb) { ctxt->input_rc = APR_EOF; return -1; } if (APR_BRIGADE_EMPTY(ctxt->input_bb)) { rc = ap_get_brigade(ctxt->input_filter->next, ctxt->input_bb, AP_MODE_READBYTES, ctxt->input_block, in); /* Not a problem, there was simply no data ready yet. */ if (APR_STATUS_IS_EAGAIN(rc) || APR_STATUS_IS_EINTR(rc) || (rc == APR_SUCCESS && APR_BRIGADE_EMPTY(ctxt->input_bb))) { if (APR_STATUS_IS_EOF(ctxt->input_rc)) { return 0; } else { if (ctxt->session) gnutls_transport_set_errno(ctxt-> session, EINTR); return -1; } } if (rc != APR_SUCCESS) { /* Unexpected errors discard the brigade */ apr_brigade_cleanup(ctxt->input_bb); ctxt->input_bb = NULL; return -1; } } ctxt->input_rc = brigade_consume(ctxt->input_bb, block, buffer, &len); if (ctxt->input_rc == APR_SUCCESS) { return (ssize_t) len; } if (APR_STATUS_IS_EAGAIN(ctxt->input_rc) || APR_STATUS_IS_EINTR(ctxt->input_rc)) { if (len == 0) { if (ctxt->session) gnutls_transport_set_errno(ctxt->session, EINTR); return -1; } return (ssize_t) len; } /* Unexpected errors and APR_EOF clean out the brigade. * Subsequent calls will return APR_EOF. */ apr_brigade_cleanup(ctxt->input_bb); ctxt->input_bb = NULL; if (APR_STATUS_IS_EOF(ctxt->input_rc) && len) { /* Provide the results of this read pass, * without resetting the BIO retry_read flag */ return (ssize_t) len; } return -1; }