ssize_t socket_send_range(const socket_st * socket, const void *buffer, int buffer_size, gnutls_range_st * range) { int ret; if (socket->secure) do { if (range == NULL) ret = gnutls_record_send(socket->session, buffer, buffer_size); else ret = gnutls_record_send_range(socket-> session, buffer, buffer_size, range); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); else do { ret = send(socket->fd, buffer, buffer_size, 0); } while (ret == -1 && errno == EINTR); if (ret > 0 && ret != buffer_size && socket->verbose) fprintf(stderr, "*** Only sent %d bytes instead of %d.\n", ret, buffer_size); return ret; }
static void server (int fd, const char* prio) { int ret; char buffer[MAX_BUF + 1]; gnutls_session_t session; gnutls_anon_server_credentials_t anoncred; gnutls_certificate_credentials_t x509_cred; gnutls_range_st range; to_send = 0; range.low = MAX_BUF; range.high = HIGH(MAX_BUF); /* this must be called once in the program */ global_init (); memset(buffer, 0, sizeof(buffer)); if (debug) { gnutls_global_set_log_function (server_log_func); gnutls_global_set_log_level (4711); } gnutls_certificate_allocate_credentials (&x509_cred); gnutls_certificate_set_x509_key_mem (x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_anon_allocate_server_credentials (&anoncred); gnutls_init (&session, GNUTLS_SERVER); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct (session, prio, NULL); gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd); do { ret = gnutls_handshake (session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { close (fd); gnutls_deinit (session); fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret)); terminate(); } if (debug) success ("server: Handshake was completed\n"); if (debug) success ("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version (session))); gnutls_transport_set_push_function (session, push); if (gnutls_record_can_use_length_hiding(session) == 0) { fail("Length hiding isn't possible\n"); terminate(); } do { do { ret = gnutls_record_send_range (session, buffer, sizeof (buffer), &range); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret < 0) { fail("Error sending packet: %s\n", gnutls_strerror(ret)); terminate(); } to_send++; } while(to_send < 4); to_send = -1; /* do not wait for the peer to close the connection. */ gnutls_bye (session, GNUTLS_SHUT_WR); close (fd); gnutls_deinit (session); gnutls_anon_free_server_credentials (anoncred); gnutls_certificate_free_credentials (x509_cred); gnutls_global_deinit (); if (debug) success ("server: finished\n"); }