nopoll_bool on_connection_opened (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data)
{
	/* set connection close */
	nopoll_conn_set_on_close (conn, __nopoll_regression_on_close, NULL);

	if (! nopoll_conn_set_sock_block (nopoll_conn_socket (conn), nopoll_false)) {
		printf ("ERROR: failed to configure non-blocking state to connection..\n");
		return nopoll_false;
	} /* end if */

	/* check to reject */
	if (nopoll_cmp (nopoll_conn_get_origin (conn), "http://deny.aspl.es"))  {
		printf ("INFO: rejected connection from %s, with Host: %s and Origin: %s\n",
			nopoll_conn_host (conn), nopoll_conn_get_host_header (conn), nopoll_conn_get_origin (conn));
		return nopoll_false;
	} /* end if */

	/* get protocol to reply an especific case. This is an example
	   on how to detect protocols requested by the client and how
	   to reply with a particular value at the server. */
	printf ("Requested protocol: %s\n", nopoll_conn_get_requested_protocol (conn));
	if (nopoll_cmp (nopoll_conn_get_requested_protocol (conn), "hello-protocol")) {
		/* set hello-protocol-response */
		nopoll_conn_set_accepted_protocol (conn, "hello-protocol-response");
	} /* end if */

	/* notify connection accepted */
	/* printf ("INFO: connection received from %s, with Host: %s and Origin: %s\n",
	   nopoll_conn_host (conn), nopoll_conn_get_host_header (conn), nopoll_conn_get_origin (conn)); */
	return nopoll_true;
}
noPollPtr ssl_context_creator (noPollCtx * ctx, noPollConn * conn, noPollConnOpts * opts, nopoll_bool is_client, noPollPtr user_data)
{
	SSL_CTX             * ssl_ctx;
	noPollConn          * listener;

	/* very basic context creation using default settings provided
	 * by OpenSSL */
	if (is_client) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
		return SSL_CTX_new (TLSv1_client_method ());
#else
	        return SSL_CTX_new (TLS_client_method ());
#endif
	} /* end if */

	/* get the ssl context */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
	ssl_ctx = SSL_CTX_new (TLSv1_server_method ());
#else
	ssl_ctx = SSL_CTX_new (TLS_server_method ());
#endif

	/* get a reference to the listener */
	listener = nopoll_conn_get_listener (conn);

	if (nopoll_cmp ("1239", nopoll_conn_port (listener))) {
		printf ("ACCEPTED ssl connection on port: %s (for conn %p)\n", nopoll_conn_port (listener), conn);

		/* ok, especiall case where we require a certain
		 * certificate from renote side */
		if (SSL_CTX_load_verify_locations (ssl_ctx, "client-side-cert-auth-cacert.crt", NULL) != 1) {
			printf ("ERROR: unable to add ca certificate...\n");
		}


		/* make server to ask for a certificate to the client
		 * .... and verify it */
		SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
	} /* end if */
	
	printf ("RETURNING: ssl context reference %p\n", ssl_ctx);
	return ssl_ctx;
}
Esempio n. 3
0
nopoll_bool test_sending_and_check_echo (noPollConn * conn, const char * label, const char * msg)
{
  char  buffer[1024];
  int   length = strlen (msg);
  int   bytes_read;

  /* wait for the reply */
  while (nopoll_true) {
    if (nopoll_conn_is_ready (conn))
      break;
    nopoll_sleep (10000);
  } /* end if */

  /* send content text(utf-8) */
  printf ("%s: sending content..\n", label);
  if (nopoll_conn_send_text (conn, msg, length) != length) {
    printf ("ERROR: Expected to find proper send operation..\n");
    return nopoll_false;
  }

  /* wait for the reply (try to read 1024, blocking and with a 3 seconds timeout) */
  bytes_read = nopoll_conn_read (conn, buffer, length, nopoll_true, 3000);
  if (bytes_read > 0)
    buffer[bytes_read] = 0;

  if (bytes_read != length) {
    printf ("ERROR: expected to find 14 bytes but found %d..\n", bytes_read);
    return nopoll_false;
  } /* end if */

  /* check content received */
  if (! nopoll_cmp (buffer, msg)) {
    printf ("ERROR: expected to find message 'This is a test' but something different was received: '%s'..\n",
	    buffer);
    return nopoll_false;
  } /* end if */

  printf ("%s: received reply and echo matches..\n", label);

  /* return that we sent and received the echo reply */
  return nopoll_true;
}
int main (int argc, char ** argv)
{
	noPollConn     * listener;
	noPollConn     * listener_6;
	noPollConn     * listener2;
	noPollConn     * listener_62;
#if defined(NOPOLL_HAVE_SSLv23_ENABLED)	
	noPollConn     * listener3;
#endif
#if defined(NOPOLL_HAVE_SSLv3_ENABLED)	
	noPollConn     * listener4;
#endif	
#if defined(NOPOLL_HAVE_TLSv11_ENABLED)
	noPollConn     * listener5;
	noPollConn     * listener_65;
#endif
	noPollConn     * listener6;
#if defined(NOPOLL_HAVE_TLSv12_ENABLED)
	noPollConn     * listener7;
#endif	
	int              iterator;
	noPollConnOpts * opts;

	signal (SIGTERM,  __terminate_listener);

#if defined(__NOPOLL_PTHREAD_SUPPORT__)	
	printf ("INFO: install default threading functions to check noPoll locking code..\n");
	nopoll_thread_handlers (__nopoll_regtest_mutex_create,
				__nopoll_regtest_mutex_destroy,
				__nopoll_regtest_mutex_lock,
				__nopoll_regtest_mutex_unlock);
#endif

	/* create the context */
	ctx = nopoll_ctx_new ();

	iterator = 1;
	while (iterator < argc) {
		/* check for debug */
		printf ("Checking agument: %s\n", argv[iterator]);
		if (nopoll_cmp (argv[iterator], "--debug")) {
			printf ("Activating debug..\n");
			nopoll_log_enable (ctx, nopoll_true);
#if !defined(NOPOLL_OS_WIN32)
			nopoll_log_color_enable (ctx, nopoll_true);
#endif
		} /* end if */

		/* next position */
		iterator++;
	} 

	/* call to create a listener */
	listener = nopoll_listener_new (ctx, "0.0.0.0", "1234");
	if (! nopoll_conn_is_ok (listener)) {
		printf ("ERROR: Expected to find proper listener connection status, but found..\n");
		return -1;
	}

	printf ("noPoll listener started at: %s:%s (refs: %d)..\n", nopoll_conn_host (listener), nopoll_conn_port (listener), nopoll_conn_ref_count (listener));

	/* call to create a listener */
	listener_6 = nopoll_listener_new6 (ctx, "::1", "2234");
	if (! nopoll_conn_is_ok (listener_6)) {
		printf ("ERROR: Expected to find proper listener connection status, but found (IPv6 -- .1.1)..\n");
		return -1;
	} /* end if */

	printf ("noPoll listener started at (IPv6): %s:%s (refs: %d)..\n", nopoll_conn_host (listener_6), nopoll_conn_port (listener_6), nopoll_conn_ref_count (listener_6));

	/* now start a TLS version */
	printf ("Test: starting listener with TLS (TLSv1) at :1235\n");
	listener2 = nopoll_listener_tls_new (ctx, "0.0.0.0", "1235");
	if (! nopoll_conn_is_ok (listener2)) {
		printf ("ERROR: Expected to find proper listener TLS connection status, but found..\n");
		return -1;
	} /* end if */

	/* configure certificates to be used by this listener */
	if (! nopoll_listener_set_certificate (listener2, "test-certificate.crt", "test-private.key", NULL)) {
		printf ("ERROR: unable to configure certificates for TLS websocket..\n");
		return -1;
	}

	/* register certificates at context level */
	if (! nopoll_ctx_set_certificate (ctx, NULL, "test-certificate.crt", "test-private.key", NULL)) {
		printf ("ERROR: unable to setup certificates at context level..\n");
		return -1;
	}

	/* now start a TLS version */
	printf ("Test: starting listener with TLS IPv6 (TLSv1) at :2235\n");
	listener_62 = nopoll_listener_tls_new6 (ctx, "::1", "2235");
	if (! nopoll_conn_is_ok (listener_62)) {
		printf ("ERROR: Expected to find proper listener TLS connection status, but found..\n");
		return -1;
	} /* end if */

	/* configure certificates to be used by this listener */
	if (! nopoll_listener_set_certificate (listener_62, "test-certificate.crt", "test-private.key", NULL)) {
		printf ("ERROR: unable to configure certificates for TLS websocket..\n");
		return -1;
	}

	/* register certificates at context level */
	if (! nopoll_ctx_set_certificate (ctx, NULL, "test-certificate.crt", "test-private.key", NULL)) {
		printf ("ERROR: unable to setup certificates at context level..\n");
		return -1;
	}

#if defined(NOPOLL_HAVE_SSLv23_ENABLED)	
	/* start listener with sslv23 */
	printf ("Test: starting listener with TLS (SSLv23) at :1236 (all methods)\n");
	opts     = nopoll_conn_opts_new ();
	nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_SSLV23);
	listener3 = nopoll_listener_tls_new_opts (ctx, opts, "0.0.0.0", "1236");
	if (! nopoll_conn_is_ok (listener3)) {
		printf ("ERROR: Expected to find proper listener TLS connection status (:1236, SSLv23), but found..\n");
		return -1;
	} /* end if */
#endif

#if defined(NOPOLL_HAVE_SSLv3_ENABLED)	
	printf ("Test: starting listener with TLS (SSLv3) at :1237\n");
	opts     = nopoll_conn_opts_new ();
	nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_SSLV3);
	listener4 = nopoll_listener_tls_new_opts (ctx, opts, "0.0.0.0", "1237");
	if (! nopoll_conn_is_ok (listener4)) {
		printf ("ERROR: Expected to find proper listener TLS connection status (:1237, SSLv3), but found..\n");
		return -1;
	} /* end if */
#endif	

#if defined(NOPOLL_HAVE_TLSv11_ENABLED)
	printf ("Test: starting listener with TLS (TLSv1.1) at :1238\n");
	opts     = nopoll_conn_opts_new ();
	nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_1);
	listener5 = nopoll_listener_tls_new_opts (ctx, opts, "0.0.0.0", "1238");
	if (! nopoll_conn_is_ok (listener5)) {
		printf ("ERROR: Expected to find proper listener TLS connection status (:1238, TLSv1.1), but found..\n");
		return -1;
	} /* end if */

	printf ("Test: starting listener with TLS (TLSv1.1) (IPv6) at :2238\n");
	opts     = nopoll_conn_opts_new ();
	nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_1);
	listener_65 = nopoll_listener_tls_new_opts6 (ctx, opts, "::1", "2238");
	if (! nopoll_conn_is_ok (listener_65)) {
		printf ("ERROR: Expected to find proper listener TLS connection status (::1:2238, TLSv1.1, IPv6), but found..\n");
		return -1;
	} /* end if */
	
#endif

#if defined(NOPOLL_HAVE_TLSv12_ENABLED)
	printf ("Test: starting listener with TLS (TLSv1.2) at :1240\n");
	opts     = nopoll_conn_opts_new ();
	nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
	listener7 = nopoll_listener_tls_new_opts (ctx, opts, "0.0.0.0", "1240");
	if (! nopoll_conn_is_ok (listener7)) {
		printf ("ERROR: Expected to find proper listener TLS connection status (:1240, TLSv1.2), but found..\n");
		return -1;
	} /* end if */
#endif

	opts     = nopoll_conn_opts_new ();

	/* configure server certificates (server.pem) signed by the
	 * provided ca (root.pem) also configured in the last
	 * parameter */
	if (! nopoll_conn_opts_set_ssl_certs (opts, 
					      "server.pem",
					      "server.pem",
					      NULL,
					      "root.pem")) {
		printf ("ERROR: unable to setup certificates...\n");
		return -1;
	}
	/* configure peer verification */
	nopoll_conn_opts_ssl_peer_verify (opts, nopoll_true);
	    
	listener6 = nopoll_listener_tls_new_opts (ctx, opts, "0.0.0.0", "1239");
	if (! nopoll_conn_is_ok (listener6)) {
		printf ("ERROR: Expected to find proper listener TLS connection status (:1236, SSLv23), but found..\n");
		return -1;
	} /* end if */


	/* configure ssl context creator */
	/* nopoll_ctx_set_ssl_context_creator (ctx, ssl_context_creator, NULL); */

	/* set on message received */
	nopoll_ctx_set_on_msg (ctx, listener_on_message, NULL);

	/* set on open */
	nopoll_ctx_set_on_open (ctx, on_connection_opened, NULL);
	
	/* process events */
	nopoll_loop_wait (ctx, 0);

	/* unref connection */
	nopoll_conn_close (listener);
	nopoll_conn_close (listener_6);  /* ipv6 */
	
	nopoll_conn_close (listener2);
	nopoll_conn_close (listener_62); /* ipv6 */
	
#if defined(NOPOLL_HAVE_SSLv23_ENABLED)	
	nopoll_conn_close (listener3);
#endif
#if defined(NOPOLL_HAVE_SSLv3_ENABLED)	
	nopoll_conn_close (listener4);
#endif	
#if defined(NOPOLL_HAVE_TLSv12_ENABLED)
	nopoll_conn_close (listener5);
	nopoll_conn_close (listener_65);
#endif
	nopoll_conn_close (listener6);
#if defined(NOPOLL_HAVE_TLSv12_ENABLED)
	nopoll_conn_close (listener7);
#endif	

	/* finish */
	printf ("Listener: finishing references: %d\n", nopoll_ctx_ref_count (ctx));
	if (previous_msg) {
		printf ("..reference counting for previous msg: %d\n", nopoll_msg_ref_count (previous_msg));
		nopoll_msg_unref (previous_msg);
	} /* end if */

	nopoll_ctx_unref (ctx);

	/* call to release all pending memory allocated as a
	 * consequence of using nopoll (especially TLS) */
	nopoll_cleanup_library ();

	return 0;
}
void listener_on_message (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data)
{
	const char * content = (const char *) nopoll_msg_get_payload (msg);
	FILE       * file = NULL;
	char         buffer[1024];
	int          bytes;
	int          sent;
	char         example[100];
	int          shown;
	noPollMsg  * aux;
	nopoll_bool  dont_reply = nopoll_false;
	FILE       * open_file_cmd = NULL;
	int          iterator;
	char       * ref;

	/* check for open file commands */
	if (nopoll_ncmp (content, "open-file: ", 11)) {
#if defined(NOPOLL_OS_WIN32)
		open_file_cmd = fopen (content + 11, "ab");
#else
		open_file_cmd = fopen (content + 11, "a");
#endif
		if (open_file_cmd == NULL) {
			printf ("ERROR: unable to open file: %s\n", content + 11);
			return;
		} /* end if */

		/* set handler */
		nopoll_conn_set_on_msg (conn, write_file_handler, open_file_cmd);

		return;
	} /* end if */

	/* printf ("Message received: %s\n", content); */
	if (nopoll_ncmp (content, "close with message", 18)) {
		printf ("Listener: RELEASING connection (closing it) with reason..\n");
		nopoll_conn_close_ext (conn, 1048, "Hey, this is a very reasonable error message", 44);
		return;
	} /* end if */

	if (nopoll_ncmp (content, "release-message", 15)) {
		printf ("Listener: RELEASING previous message..\n");
		nopoll_msg_unref (previous_msg);
		previous_msg = NULL;
		return;
	} /* end if */
	if (nopoll_ncmp (content, "get-cookie", 10)) {
		printf ("Listener: reporting cookie: %s\n", nopoll_conn_get_cookie (conn));
		nopoll_conn_send_text (conn, nopoll_conn_get_cookie (conn), strlen (nopoll_conn_get_cookie (conn)));
		return;
	}

	/* printf ("Checking for set-broken socket: %s\n", content); */
	if (nopoll_ncmp (content, "set-broken-socket", 17)) {
		printf ("Listener: setting broken socket on conn: %p (socket=%d)\n",
			conn, (int) nopoll_conn_socket (conn));
		nopoll_conn_shutdown (conn);
		return;
	} /* end if */

	if (nopoll_ncmp (content, "get-connection-close-count", 26)) {
		printf ("Sending reply to report connection close...\n");
		ref = nopoll_strdup_printf ("%d", connection_close_count);
		nopoll_conn_send_text (conn, ref, strlen (ref));
		nopoll_free (ref);
		return;
	} /* end if */

	if (nopoll_ncmp (content, "1234-1) ", 8)) {
		printf ("Listener: waiting a second to force buffer flooding..\n");
		nopoll_sleep (100000);
		dont_reply = nopoll_true;
	} /* end if */

	/* get initial bytes */
	bytes = nopoll_msg_get_payload_size (msg);
	shown = bytes > 100 ? 99 : bytes;

	memset (example, 0, 100);
	/*	if (! nopoll_msg_is_fragment (msg)) */
		memcpy (example, (const char *) nopoll_msg_get_payload (msg), shown);

	printf ("Listener received (size: %d, ctx refs: %d): (first %d bytes, fragment: %d) '%s'\n", 
		nopoll_msg_get_payload_size (msg),
		nopoll_ctx_ref_count (ctx), shown, nopoll_msg_is_fragment (msg), example);

	if (nopoll_cmp (content, "ping")) {
		/* send a ping */
		nopoll_conn_send_ping (conn);
		return;
	} else if (nopoll_cmp (content, "get-file")) {
		iterator = 0;
		file     = NULL;
		while (nopoll_true) {
#if defined(NOPOLL_OS_WIN32)
			file = fopen ("nopoll-regression-client.c", "rb");
#else
			file = fopen ("nopoll-regression-client.c", "r");
#endif		
			printf ("LISTENER: file pointer (%p, errno=%d : %s)..\n", file, errno, strerror (errno));
			
			if (file)
				break;
			iterator++;
			if (iterator > 3) {
				printf ("ERROR: failed to open nopoll-regression-client.c (fopen call failed)\n");
				nopoll_conn_shutdown (conn);
				return;
			} /* end if */
		} /* end while */

		while (! feof (file)) {
			/* read content */
			bytes = fread (buffer, 1, 1024, file);
			/* send content */
			if (bytes > 0) {
				/* send content and get the result */
				/* printf ("Sending message with %d bytes..\n", bytes); */
				/* nopoll_log_enable (ctx, nopoll_true); */
				
				while (nopoll_true) {
					/* try to send content */
					sent = nopoll_conn_send_text (conn, buffer, bytes);
					/* nopoll_log_enable (ctx, nopoll_false); */
					if (sent != bytes) {
						if (errno == NOPOLL_EWOULDBLOCK) {
							nopoll_sleep (1000);
							/* printf ("   ..retrying..sending message with %d bytes..\n", bytes); */
							continue;
						} /* end if */
						printf ("ERROR: expected to send %d bytes but sent different content size (%d bytes), errno=%d (%d)..\n", 
							bytes, sent, errno, NOPOLL_EWOULDBLOCK);
					} /* end if */
					break;
				}
			} /* end if */
			/* next */
		} /* end while */

		/* now close the handle */
		fclose (file);
		return;
	} /* end if */

	/* check if we have to reply */
	if (dont_reply)
		return;

	if (nopoll_msg_is_fragment (msg)) {
		printf ("Found fragment, FIN = %d (%p)?..\n", nopoll_msg_is_final (msg), msg);
		/* call to join this message */
		aux          = previous_msg;
		previous_msg = nopoll_msg_join (previous_msg, msg);
		nopoll_msg_unref (aux);
		if (! nopoll_msg_is_final (msg)) {
			printf ("Found fragment that is not final..\n");
			printf ("Not replying because frame fragment received..\n");
			return;
		} /* end if */

		printf ("Found final fragment, replying with complete content: %s (refs: %d)..\n",
			(const char *) nopoll_msg_get_payload (previous_msg), 
			nopoll_msg_ref_count (previous_msg));

		/* ok, now found final piece, replying */
		nopoll_conn_send_text (conn, (const char *) nopoll_msg_get_payload (previous_msg), 
				       nopoll_msg_get_payload_size (previous_msg));
		/* release reference */
		nopoll_msg_unref (previous_msg);
		previous_msg = NULL;

		return;
	}

	/* send reply as received */
	printf ("Sending reply... (same message size: %d)\n", nopoll_msg_get_payload_size (msg));
	nopoll_conn_send_text (conn, (const char *) nopoll_msg_get_payload (msg), 
			       nopoll_msg_get_payload_size (msg));
	return;
}