diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-12-27 23:32:12 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-12-28 16:08:55 +0200 |
commit | d2ff834b0b7224f808eea3e2f3cda0b8d0f17a08 (patch) | |
tree | ff86499bee086b4c98c9aa8cd2054d5a941fec22 | |
parent | 89ee549eb59e2d627548bb79e2ccfa589791d98c (diff) | |
download | gnutls-d2ff834b0b7224f808eea3e2f3cda0b8d0f17a08.tar.gz |
updated server examples
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | doc/examples/ex-serv-dtls.c | 258 | ||||
-rw-r--r-- | doc/examples/ex-serv1.c | 22 |
3 files changed, 153 insertions, 128 deletions
diff --git a/.gitignore b/.gitignore index 7e45f1417d..f06f9f3168 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ doc/examples/ex-serv-pgp doc/examples/ex-serv-psk doc/examples/ex-serv-srp doc/examples/ex-serv1 +doc/examples/ex-serv-dtls doc/examples/libexamples.la doc/extra.c.texi doc/gnutls-api.texi diff --git a/doc/examples/ex-serv-dtls.c b/doc/examples/ex-serv-dtls.c index bdcbe3bb61..52c96c328b 100644 --- a/doc/examples/ex-serv-dtls.c +++ b/doc/examples/ex-serv-dtls.c @@ -24,31 +24,32 @@ #define CRLFILE "crl.pem" /* This is a sample DTLS echo server, using X.509 authentication. + * Note that error checking is minimal to simplify the example. */ -#define SA struct sockaddr -#define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);} #define MAX_BUFFER 1024 -#define PORT 5556 /* listen to 5556 port */ +#define PORT 5556 -typedef struct { +typedef struct +{ gnutls_session_t session; int fd; - struct sockaddr * cli_addr; + struct sockaddr *cli_addr; socklen_t cli_addr_size; } priv_data_st; -static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms); -static ssize_t push_func (gnutls_transport_ptr_t p, const void * data, size_t size); -static ssize_t pull_func(gnutls_transport_ptr_t p, void * data, size_t size); -static const char * -human_addr (const struct sockaddr *sa, socklen_t salen, - char *buf, size_t buflen); -static int wait_for_connection(int fd); +static int pull_timeout_func (gnutls_transport_ptr_t ptr, unsigned int ms); +static ssize_t push_func (gnutls_transport_ptr_t p, const void *data, + size_t size); +static ssize_t pull_func (gnutls_transport_ptr_t p, void *data, size_t size); +static const char *human_addr (const struct sockaddr *sa, socklen_t salen, + char *buf, size_t buflen); +static int wait_for_connection (int fd); static gnutls_session_t initialize_tls_session (void); static int generate_dh_params (void); -/* These are global */ +/* Use global credentials and parameters to simplify + * the example. */ static gnutls_certificate_credentials_t x509_cred; static gnutls_priority_t priority_cache; static gnutls_dh_params_t dh_params; @@ -56,7 +57,7 @@ static gnutls_dh_params_t dh_params; int main (void) { - int err, listen_sd; + int listen_sd; int sock, ret; struct sockaddr_in sa_serv; struct sockaddr_in cli_addr; @@ -80,99 +81,105 @@ main (void) gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE, GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE, + ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE, GNUTLS_X509_FMT_PEM); + if (ret < 0) + { + printf("No certificate or key were found\n"); + exit(1); + } generate_dh_params (); gnutls_certificate_set_dh_params (x509_cred, dh_params); - ret = gnutls_priority_init (&priority_cache, "NORMAL:-VERS-TLS-ALL:+VERS-DTLS1.0", NULL); - if (ret < 0) - { - fprintf(stderr, "Error in the priority string\n"); - exit(1); - } + gnutls_priority_init (&priority_cache, + "NORMAL:-VERS-TLS-ALL:+VERS-DTLS1.0", NULL); - ret = gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE); - if (ret < 0) - { - fprintf(stderr, "Cannot generate key\n"); - exit(1); - } + gnutls_key_generate (&cookie_key, GNUTLS_COOKIE_KEY_SIZE); /* Socket operations */ listen_sd = socket (AF_INET, SOCK_DGRAM, 0); - SOCKET_ERR (listen_sd, "socket"); memset (&sa_serv, '\0', sizeof (sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; - sa_serv.sin_port = htons (PORT); /* Server Port number */ + sa_serv.sin_port = htons (PORT); -#ifdef IP_DONTFRAG - { + { /* DTLS requires the IP don't fragment (DF) bit to be set */ +#if defined(IP_DONTFRAG) int optval = 1; - if (setsockopt (s, IPPROTO_IP, IP_DONTFRAG, - (const void *) &optval, sizeof (optval)) < 0) - { - perror ("setsockopt(IP_DF) failed"); - } - } + setsockopt (listen_sd, IPPROTO_IP, IP_DONTFRAG, + (const void *) &optval, sizeof (optval)); +#elif defined(IP_MTU_DISCOVER) + int optval = IP_PMTUDISC_DO; + setsockopt(listen_sd, IPPROTO_IP, IP_MTU_DISCOVER, + (const void*) &optval, sizeof (optval)); #endif - err = bind (listen_sd, (SA *) &sa_serv, sizeof (sa_serv)); - SOCKET_ERR (err, "bind"); + } + + bind (listen_sd, (struct sockaddr *) &sa_serv, sizeof (sa_serv)); printf ("UDP server ready. Listening to port '%d'.\n\n", PORT); for (;;) { - printf("Waiting for connection...\n"); - sock = wait_for_connection(listen_sd); + printf ("Waiting for connection...\n"); + sock = wait_for_connection (listen_sd); if (sock < 0) continue; - cli_addr_size = sizeof(cli_addr); - ret = recvfrom(sock, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr*)&cli_addr, &cli_addr_size); + cli_addr_size = sizeof (cli_addr); + ret = recvfrom (sock, buffer, sizeof (buffer), MSG_PEEK, + (struct sockaddr *) &cli_addr, &cli_addr_size); if (ret > 0) { - memset(&prestate, 0, sizeof(prestate)); - ret = gnutls_dtls_cookie_verify(&cookie_key, &cli_addr, sizeof(cli_addr), buffer, ret, &prestate); - if (ret < 0) /* cookie not valid */ + memset (&prestate, 0, sizeof (prestate)); + ret = gnutls_dtls_cookie_verify (&cookie_key, &cli_addr, + sizeof (cli_addr), buffer, ret, + &prestate); + if (ret < 0) /* cookie not valid */ { priv_data_st s; - - memset(&s, 0, sizeof(s)); + + memset (&s, 0, sizeof (s)); s.fd = sock; - s.cli_addr = (void*)&cli_addr; - s.cli_addr_size = sizeof(cli_addr); - - printf("Sending hello verify request to %s\n", human_addr ((struct sockaddr *) - &cli_addr, sizeof(cli_addr), buffer, sizeof(buffer))); - gnutls_dtls_cookie_send(&cookie_key, &cli_addr, sizeof(cli_addr), &prestate, (gnutls_transport_ptr_t)&s, push_func); - - /* discard peeked data*/ - recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&cli_addr, &cli_addr_size); - usleep(100); + s.cli_addr = (void *) &cli_addr; + s.cli_addr_size = sizeof (cli_addr); + + printf ("Sending hello verify request to %s\n", + human_addr ((struct sockaddr *) &cli_addr, + sizeof (cli_addr), buffer, + sizeof (buffer))); + + gnutls_dtls_cookie_send (&cookie_key, &cli_addr, + sizeof (cli_addr), &prestate, + (gnutls_transport_ptr_t) & s, + push_func); + + /* discard peeked data */ + recvfrom (sock, buffer, sizeof (buffer), 0, + (struct sockaddr *) &cli_addr, &cli_addr_size); + usleep (100); continue; } printf ("Accepted connection from %s\n", human_addr ((struct sockaddr *) - &cli_addr, sizeof(cli_addr), buffer, - sizeof (buffer))); + &cli_addr, sizeof (cli_addr), buffer, + sizeof (buffer))); } else continue; session = initialize_tls_session (); - gnutls_dtls_prestate_set(session, &prestate); - gnutls_dtls_set_mtu(session, mtu); + gnutls_dtls_prestate_set (session, &prestate); + gnutls_dtls_set_mtu (session, mtu); priv.session = session; priv.fd = sock; - priv.cli_addr = (struct sockaddr *)&cli_addr; - priv.cli_addr_size = sizeof(cli_addr); + priv.cli_addr = (struct sockaddr *) &cli_addr; + priv.cli_addr_size = sizeof (cli_addr); gnutls_transport_set_ptr (session, &priv); gnutls_transport_set_push_function (session, push_func); @@ -181,45 +188,51 @@ main (void) do { - ret = gnutls_handshake(session); + ret = gnutls_handshake (session); } - while(gnutls_error_is_fatal(ret) == 0); + while (gnutls_error_is_fatal (ret) == 0); if (ret < 0) { - fprintf(stderr, "Error in handshake(): %s\n", gnutls_strerror(ret)); - gnutls_deinit(session); + fprintf (stderr, "Error in handshake(): %s\n", + gnutls_strerror (ret)); + gnutls_deinit (session); continue; } printf ("- Handshake was completed\n"); - for(;;) + for (;;) { - do { - ret = gnutls_record_recv_seq(session, buffer, MAX_BUFFER, sequence); - } while(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); + do + { + ret = gnutls_record_recv_seq (session, buffer, MAX_BUFFER, + sequence); + } + while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret < 0) { - fprintf(stderr, "Error in recv(): %s\n", gnutls_strerror(ret)); + fprintf (stderr, "Error in recv(): %s\n", + gnutls_strerror (ret)); break; } if (ret == 0) { - printf("EOF\n\n"); + printf ("EOF\n\n"); break; } buffer[ret] = 0; - printf("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", sequence[0], - sequence[1], sequence[2], sequence[3], sequence[4], sequence[5], - sequence[6], sequence[7], buffer); + printf ("received[%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x]: %s\n", + sequence[0], sequence[1], sequence[2], sequence[3], + sequence[4], sequence[5], sequence[6], sequence[7], buffer); /* reply back */ - ret = gnutls_record_send(session, buffer, ret); + ret = gnutls_record_send (session, buffer, ret); if (ret < 0) { - fprintf(stderr, "Error in send(): %s\n", gnutls_strerror(ret)); + fprintf (stderr, "Error in send(): %s\n", + gnutls_strerror (ret)); break; } } @@ -239,7 +252,8 @@ main (void) } -static int wait_for_connection(int fd) +static int +wait_for_connection (int fd) { fd_set rd, wr; int n; @@ -264,23 +278,24 @@ static int wait_for_connection(int fd) /* Wait for data to be received within a timeout period in milliseconds */ -static int pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms) +static int +pull_timeout_func (gnutls_transport_ptr_t ptr, unsigned int ms) { -fd_set rfds; -struct timeval tv; -priv_data_st *priv = ptr; -struct sockaddr_in cli_addr; -socklen_t cli_addr_size; -int ret; -char c; - - FD_ZERO(&rfds); - FD_SET(priv->fd, &rfds); - + fd_set rfds; + struct timeval tv; + priv_data_st *priv = ptr; + struct sockaddr_in cli_addr; + socklen_t cli_addr_size; + int ret; + char c; + + FD_ZERO (&rfds); + FD_SET (priv->fd, &rfds); + tv.tv_sec = 0; tv.tv_usec = ms * 1000; - - ret = select(priv->fd+1, &rfds, NULL, NULL, &tv); + + ret = select (priv->fd + 1, &rfds, NULL, NULL, &tv); if (ret <= 0) return ret; @@ -288,46 +303,54 @@ char c; /* only report ok if the next message is from the peer we expect * from */ - cli_addr_size = sizeof(cli_addr); - ret = recvfrom(priv->fd, &c, 1, MSG_PEEK, (struct sockaddr*)&cli_addr, &cli_addr_size); + cli_addr_size = sizeof (cli_addr); + ret = + recvfrom (priv->fd, &c, 1, MSG_PEEK, (struct sockaddr *) &cli_addr, + &cli_addr_size); if (ret > 0) { - if (cli_addr_size == priv->cli_addr_size && memcmp(&cli_addr, priv->cli_addr, sizeof(cli_addr))==0) + if (cli_addr_size == priv->cli_addr_size + && memcmp (&cli_addr, priv->cli_addr, sizeof (cli_addr)) == 0) return 1; } return 0; } -static ssize_t push_func (gnutls_transport_ptr_t p, const void * data, size_t size) +static ssize_t +push_func (gnutls_transport_ptr_t p, const void *data, size_t size) { -priv_data_st *priv = p; + priv_data_st *priv = p; - return sendto(priv->fd, data, size, 0, priv->cli_addr, priv->cli_addr_size); + return sendto (priv->fd, data, size, 0, priv->cli_addr, + priv->cli_addr_size); } -static ssize_t pull_func(gnutls_transport_ptr_t p, void * data, size_t size) +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); + 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) + 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); + human_addr ((struct sockaddr *) + &cli_addr, sizeof (cli_addr), buffer, sizeof (buffer))); + + gnutls_transport_set_errno (priv->session, EAGAIN); return -1; } @@ -384,7 +407,7 @@ initialize_tls_session (void) { gnutls_session_t session; - gnutls_init (&session, GNUTLS_SERVER|GNUTLS_DATAGRAM); + gnutls_init (&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_priority_set (session, priority_cache); @@ -393,7 +416,8 @@ initialize_tls_session (void) return session; } -static int generate_dh_params (void) +static int +generate_dh_params (void) { int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW); diff --git a/doc/examples/ex-serv1.c b/doc/examples/ex-serv1.c index 97eba2f729..eaf09f6474 100644 --- a/doc/examples/ex-serv1.c +++ b/doc/examples/ex-serv1.c @@ -23,9 +23,6 @@ /* This is a sample TLS 1.0 echo server, using X.509 authentication. */ - -#define SA struct sockaddr -#define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);} #define MAX_BUF 1024 #define PORT 5556 /* listen to 5556 port */ @@ -71,7 +68,7 @@ generate_dh_params (void) int main (void) { - int err, listen_sd; + int listen_sd; int sd, ret; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; @@ -92,8 +89,13 @@ main (void) gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE, GNUTLS_X509_FMT_PEM); - gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE, + ret = gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE, GNUTLS_X509_FMT_PEM); + if (ret < 0) + { + printf("No certificate or key were found\n"); + exit(1); + } generate_dh_params (); @@ -105,7 +107,6 @@ main (void) /* Socket operations */ listen_sd = socket (AF_INET, SOCK_STREAM, 0); - SOCKET_ERR (listen_sd, "socket"); memset (&sa_serv, '\0', sizeof (sa_serv)); sa_serv.sin_family = AF_INET; @@ -115,10 +116,9 @@ main (void) setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, sizeof (int)); - err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv)); - SOCKET_ERR (err, "bind"); - err = listen (listen_sd, 1024); - SOCKET_ERR (err, "listen"); + bind (listen_sd, (struct sockaddr *) & sa_serv, sizeof (sa_serv)); + + listen (listen_sd, 1024); printf ("Server ready. Listening to port '%d'.\n\n", PORT); @@ -127,7 +127,7 @@ main (void) { session = initialize_tls_session (); - sd = accept (listen_sd, (SA *) & sa_cli, &client_len); + sd = accept (listen_sd, (struct sockaddr *) & sa_cli, &client_len); printf ("- connection from %s, port %d\n", inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, |