DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
socket.c File Reference

Echo server using 1 server and 2 clients. More...

#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <dtsapp.h>

Go to the source code of this file.

Functions

void accept_func (struct fwsocket *sock, void *data)
 This function does nothing and is here for completeness. More...
 
void server_func (struct fwsocket *sock, void *data)
 Server thread data is available. More...
 
void client_func (struct fwsocket *sock, void *data)
 client thread data is available. More...
 
void socktest (const char *ipaddr, int tcp, int ssl)
 Bassed on the options create server and clients. More...
 
void unixsocktest (const char *socket, int protocol)
 Same test as for socktest() but for unix domain sockets. More...
 
 FRAMEWORK_MAIN ("Socket Client/Server Echo (TCP/TLS/UDP/DTLS)","Gregory Hinton Nietsky","gregory@distrotech.co.za","http://www.distrotech.co.za", 2013,"/var/run/sockettest", FRAMEWORK_FLAG_DAEMONLOCK, NULL)
 Initialise the application under the library replacing main() More...
 

Detailed Description

Echo server using 1 server and 2 clients.

Simple implementation of a echo server shoeing the network socket interface it creates 1 server and 2 client threads the server echos back what is sent. the sockets support ipv4 and ipv6 and can be UDP or TCP with or without TLS/SSL support.
On application start using FRAMEWORK_MAIN a licence banner is displayed no flags are set as i wish to daemonize after checking the command line arguments.
There is a run/lock file created failure to lock this file prevents execution.
Once the sockets are created and threads started i sleep the main thread for 5 seconds before exiting the system will make sure all threads stop before leaving.
As you can see the progam initiliztion and flow has been greatly simplified by having these tasks managed.

Definition in file socket.c.

Function Documentation

void accept_func ( struct fwsocket sock,
void *  data 
)

This function does nothing and is here for completeness.

When a new connection is recieved this function will be executed to allow processing of the connection.

Parameters
sockReference to new socket
dataReference to data suppled on thread start
Examples:
socket.c.

Definition at line 36 of file socket.c.

Referenced by socktest().

36  {
37 }
void client_func ( struct fwsocket sock,
void *  data 
)

client thread data is available.

There is no need to worry about UDP support in client trhead callbacks and use of socketread / socketwrite is all that is required.

Parameters
sockReference to socket data is available on.
dataReference to data held by thread.
Examples:
socket.c.

Definition at line 66 of file socket.c.

References fwsocket::sock, socketread(), and socketwrite().

Referenced by socktest(), and unixsocktest().

66  {
67  char buff[128];
68 
69  if (socketread(sock, &buff, 128) > 0) {
70  socketwrite(sock, &buff, strlen(buff) + 1);
71  printf("[C] %s %i\n", buff, sock->sock);
72  }
73 }
int socketread(struct fwsocket *sock, void *buf, int num)
Read from a socket into a buffer.
Definition: sslutil.c:489
int socketwrite(struct fwsocket *sock, const void *buf, int num)
Write a buffer to a socket.
Definition: sslutil.c:629
int sock
Socket FD.
Definition: dtsapp.h:133
uint8_t * buff
Buffer with compressed/uncompressed data.
Definition: dtsapp.h:166
FRAMEWORK_MAIN ( "Socket Client/Server Echo (TCP/TLS/UDP/DTLS)"  ,
"Gregory Hinton Nietsky"  ,
"gregory@distrotech.co.za"  ,
"http://www.distrotech.co.za"  ,
2013  ,
"/var/run/sockettest"  ,
FRAMEWORK_FLAG_DAEMONLOCK  ,
NULL   
)

Initialise the application under the library replacing main()

See Also
FRAMEWORK_MAIN()
framework_mkcore()
framework_init()

[main]

[main]

Examples:
socket.c.

Definition at line 167 of file socket.c.

References daemonize(), socktest(), and unixsocktest().

168  ://www.distrotech.co.za", 2013, "/var/run/sockettest", FRAMEWORK_FLAG_DAEMONLOCK, NULL) {
169 
170  if (argc < 3) {
171 #ifndef __WIN32
172  printf("Requires arguments %s [tcp|tls|udp|dtls|unix_d|unix_s] [ipaddr|socket]\n", argv[0]);
173 #else
174  printf("Requires arguments %s [tcp|tls|udp|dtls] ipaddr\n", argv[0]);
175 #endif
176  return (-1);
177  }
178 
179  daemonize();
182  if (!strcmp(argv[1], "udp")) {
183  socktest(argv[2], 0, 0);
184  } else if (!strcmp(argv[1], "dtls")) {
185  socktest(argv[2], 0, 1);
186  } else if (!strcmp(argv[1], "tcp")) {
187  socktest(argv[2], 1, 0);
188  } else if (!strcmp(argv[1], "tls")) {
189  socktest(argv[2], 1, 1);
190 #ifndef __WIN32
191  } else if (!strcmp(argv[1], "unix_d")) {
192  unixsocktest(argv[2], SOCK_DGRAM);
193  } else if (!strcmp(argv[1], "unix_s")) {
194  unixsocktest(argv[2], SOCK_STREAM);
195 #endif
196  } else {
197  printf("Invalid Option\n");
198  }
199 }
void socktest(const char *ipaddr, int tcp, int ssl)
Bassed on the options create server and clients.
Definition: socket.c:86
void unixsocktest(const char *socket, int protocol)
Same test as for socktest() but for unix domain sockets.
Definition: socket.c:139
void daemonize()
Daemonise the application using fork/exit.
Definition: main.c:94
void server_func ( struct fwsocket sock,
void *  data 
)

Server thread data is available.

This function executes when the server socket has data to read the socket will need to be read from using socketread[_d] socketread_d is a wrapper arround recvfrom and socketwerite_d is a wrapper arround sendto this is important when dealing with un encrypted UDP sessions where the socket needs sendto addresss to send data too.

Parameters
sockReference to socket data is available on.
dataReference to data held by thread.
Examples:
socket.c.

Definition at line 48 of file socket.c.

References fwsocket::sock, socketread_d(), and socketwrite_d().

Referenced by socktest(), and unixsocktest().

48  {
49  char buff[128];
50  union sockstruct addr;
51 
52  if (socketread_d(sock, &buff, 128, &addr) > 0) {
53  socketwrite_d(sock, &buff, strlen(buff) + 1, &addr);
54  printf("[S] %s %i\n", buff, sock->sock);
55  sleep(1);
56  }
57 }
int sock
Socket FD.
Definition: dtsapp.h:133
int socketread_d(struct fwsocket *sock, void *buf, int num, union sockstruct *addr)
Read from a socket into a buffer.
Definition: sslutil.c:406
uint8_t * buff
Buffer with compressed/uncompressed data.
Definition: dtsapp.h:166
int socketwrite_d(struct fwsocket *sock, const void *buf, int num, union sockstruct *addr)
Write a buffer to a socket.
Definition: sslutil.c:508
Socket union describing all address types.
Definition: dtsapp.h:80
void socktest ( const char *  ipaddr,
int  tcp,
int  ssl 
)

Bassed on the options create server and clients.

  • If SSL / TLS was requested create SSL/TLS sessions to use.
  • Bind to server and connect the clients.
  • Start threads.
  • Send data to server.
  • Sleep
Parameters
ipaddrAs supplied on the command line
tcpSet to non zero if using TCP.
sslSet to non zero if TLS/SSL is required.
Examples:
socket.c.

Definition at line 86 of file socket.c.

References accept_func(), client_func(), close_socket(), dtlsv1_init(), server_func(), socketclient(), socketserver(), socketwrite(), sslv3_init(), tcpbind(), tcpconnect(), udpbind(), and udpconnect().

Referenced by FRAMEWORK_MAIN().

86  {
87  struct fwsocket *serv, *client, *client2;
88  void *ssl_c = NULL, *ssl_s = NULL, *ssl_c2 = NULL;
89  char *buff = "client 1";
90  char *buff2 = "client 2";
91  int cnt;
92 
93  if (ssl && tcp) {
94  ssl_s = sslv3_init("certs/cacert.pem", "certs/server-cert.pem", "certs/server-key.pem", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE);
95  ssl_c = sslv3_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
96  ssl_c2 = sslv3_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
97  } else if (ssl) {
98  ssl_s = dtlsv1_init("certs/cacert.pem", "certs/server-cert.pem", "certs/server-key.pem", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE);
99  ssl_c = dtlsv1_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
100  ssl_c2 = dtlsv1_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
101  }
102 
103  if (tcp) {
104  serv = tcpbind(ipaddr, "1111", ssl_s, 10);
105  client = tcpconnect(ipaddr, "1111", ssl_c);
106  client2 = tcpconnect(ipaddr, "1111", ssl_c2);
107  } else {
108  serv = udpbind(ipaddr, "1111", ssl_s);
109  client = udpconnect(ipaddr, "1111", ssl_c);
110  client2 = udpconnect(ipaddr, "1111", ssl_c2);
111  }
112 
113  if (serv && client && client2) {
114  socketserver(serv, server_func, accept_func, NULL, NULL);
115  socketclient(client, NULL, client_func, NULL);
116  socketclient(client2, NULL, client_func, NULL);
117 
118  socketwrite(client, buff, strlen(buff)+1);
119  socketwrite(client2, buff2, strlen(buff2)+1);
120 
121  sleep(5);
122  } else {
123  printf("ERROR\n");
124  }
125 
126  close_socket(client);
127  close_socket(client2);
128  close_socket(serv);
129 }
void * sslv3_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for SSLv3.
Definition: sslutil.c:311
Socket data structure.
Definition: dtsapp.h:131
void server_func(struct fwsocket *sock, void *data)
Server thread data is available.
Definition: socket.c:48
struct fwsocket * tcpbind(const char *ipaddr, const char *port, void *ssl, int backlog)
Generic server socket.
Definition: socket.c:315
int socketwrite(struct fwsocket *sock, const void *buf, int num)
Write a buffer to a socket.
Definition: sslutil.c:629
void * dtlsv1_init(const char *cacert, const char *cert, const char *key, int verify)
Create a SSL structure for DTLSv1.
Definition: sslutil.c:325
void close_socket(struct fwsocket *sock)
Mark the socket for closure and release the reference.
Definition: socket.c:79
struct ssldata * ssl
SSL structure for encryption.
Definition: dtsapp.h:146
struct fwsocket * udpconnect(const char *ipaddr, const char *port, void *ssl)
UDP Socket client.
Definition: socket.c:262
void accept_func(struct fwsocket *sock, void *data)
This function does nothing and is here for completeness.
Definition: socket.c:36
void socketserver(struct fwsocket *sock, socketrecv connectfunc, socketrecv acceptfunc, threadcleanup cleanup, void *data)
Create a server thread with a socket that has been created with sockbind udpbind or tcpbind...
Definition: socket.c:463
struct fwsocket * udpbind(const char *ipaddr, const char *port, void *ssl)
UDP server socket.
Definition: socket.c:302
void socketclient(struct fwsocket *sock, void *data, socketrecv read, threadcleanup cleanup)
Create a server thread with a socket that has been created with sockbind udpbind or tcpbind...
Definition: socket.c:493
void client_func(struct fwsocket *sock, void *data)
client thread data is available.
Definition: socket.c:66
struct fwsocket * tcpconnect(const char *ipaddr, const char *port, void *ssl)
TCP Socket client.
Definition: socket.c:274
void unixsocktest ( const char *  socket,
int  protocol 
)

Same test as for socktest() but for unix domain sockets.

Unix domain sockets are "file" sockets and function in similar way to network sockets there scope is local to the machine so are often used for inter process control and networkless services. Instead of a IP address a file name is specified that is created by the server.

Parameters
socketFile name to create server on and connect too.
protocolTheis is either SOCK_STREAM or SOCK_DGRAM and are similar to TCP/UDP respectivly.
Examples:
socket.c.

Definition at line 139 of file socket.c.

References client_func(), close_socket(), server_func(), socketwrite_d(), unixsocket_client(), and unixsocket_server().

Referenced by FRAMEWORK_MAIN().

139  {
140  char *buff = "client 1";
141  char *buff2 = "client 2";
142  struct fwsocket *client, *client2, *server;
143 
144  server = unixsocket_server(socket, protocol, S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH, server_func, NULL);
145  sleep(1); /*wait for socket*/
146  client = unixsocket_client(socket, protocol, client_func, NULL);
147  client2 = unixsocket_client(socket, protocol, client_func, NULL);
148 
149  socketwrite_d(client, buff, strlen(buff)+1, NULL);
150  socketwrite_d(client2, buff2, strlen(buff2)+1, NULL);
151 
152  sleep(5);
153 
154  close_socket(client);
155  close_socket(client2);
156  close_socket(server);
157 }
struct fwsocket * unixsocket_client(const char *sock, int protocol, socketrecv read, void *data)
Create a client thread on the socket.
Definition: unixsock.c:310
Socket data structure.
Definition: dtsapp.h:131
void server_func(struct fwsocket *sock, void *data)
Server thread data is available.
Definition: socket.c:48
void close_socket(struct fwsocket *sock)
Mark the socket for closure and release the reference.
Definition: socket.c:79
int socketwrite_d(struct fwsocket *sock, const void *buf, int num, union sockstruct *addr)
Write a buffer to a socket.
Definition: sslutil.c:508
void client_func(struct fwsocket *sock, void *data)
client thread data is available.
Definition: socket.c:66
struct fwsocket * unixsocket_server(const char *sock, int protocol, int mask, socketrecv read, void *data)
Create and run UNIX server socket thread.
Definition: unixsock.c:277