1 /*
2  * EXAMPLE: Blocking & Cleartext ECHO SERVER (via Global Socket).
3  *
4  * Server:
5  * $ ./gs-helloworld -l
6  *
7  * Client:
8  * $ ./gs-helloworld
9  *
10  * Features:
11  * CLEARTEXT TCP
12  *		Libgsocket connects two peers through the GS-Network with each other.
13  *		Libgsocket then makes the (connected) Unix File Descriptor
14  *		(TCP socket) available to the application.
15  *
16  * 		This examples uses cleartext TCP and read()/write() calls to
17  *		exchange data from one peer to the other peer via the GS-Network.
18  */
19 #include "common.h"
20 #include "utils.h"
21 
22 /*
23  * Read from 'in' and write to 'out'.
24  */
25 static void
relay(int in,int out,const char * str)26 relay(int in, int out, const char *str)
27 {
28 	char buf[1024];
29 	char info[64];
30 	ssize_t rlen, wlen;
31 
32 	rlen = read(in, buf, sizeof buf);
33 	if (rlen < 0)
34 		ERREXIT("closed...(fd = %d, ret = %zd)\n", in, rlen);
35 	if (rlen == 0)
36 		exit(0);	/* EOF */
37 
38 	/* Output information of what we received */
39 	if (str != NULL)
40 	{
41 		snprintf(info, sizeof info, "%zd bytes ", rlen);
42 		wlen = write(STDOUT_FILENO, info, strlen(info));
43 		wlen = write(STDOUT_FILENO, str, strlen(str));
44 		XASSERT(wlen > 0, "write(): %s\n", strerror(errno));
45 	}
46 	wlen = write(out, buf, rlen);
47 	if (wlen <= 0)
48 		ERREXIT("closed...(fd = %d)\n", out);
49 }
50 
51 /*
52  * An Echo-Server: Send back whatever is received...
53  */
54 static void
do_server(void)55 do_server(void)
56 {
57 	GS *gs;
58 
59 	GS_listen(gopt.gsocket, 1);
60 	gs = GS_accept(gopt.gsocket, NULL);
61 	if (gs == NULL)
62 		ERREXIT("%s\n", GS_strerror(gopt.gsocket));
63 
64 	/* Accepted 1 connection.
65 	 * The listening socket is no longer needed and we can close it.
66 	 */
67 	GS_close(gopt.gsocket);
68 
69 	int fd = GS_get_fd(gs);
70 	while (1)
71 	{
72 		relay(fd, fd, "From Client\n");
73 	}
74 
75 	GS_close(gs);
76 }
77 
78 
79 static void
do_client(void)80 do_client(void)
81 {
82 	int ret;
83 
84 	ret = GS_connect(gopt.gsocket);
85 	if (ret != 0)
86 		ERREXIT("%s\n", GS_strerror(gopt.gsocket));
87 
88 	int fd = GS_get_fd(gopt.gsocket);
89 
90 	while (1)
91 	{
92 		/* Read from STDIN and write to gsocket */
93 		relay(0, fd, NULL);
94 		/* Read reply from gsocket and write to STDOUT */
95 		relay(fd, 1, "From Server: ");
96 	}
97 
98 	GS_close(gopt.gsocket);
99 }
100 
101 static void
my_getopt(int argc,char * argv[])102 my_getopt(int argc, char *argv[])
103 {
104 	int c;
105 
106 	do_getopt(argc, argv);	/* from utils.c */
107 
108 	optind = 1;
109 	while ((c = getopt(argc, argv, UTILS_GETOPT_STR)) != -1)
110 	{
111 		switch (c)
112 		{
113 			default:
114 				break;
115 			case '?':
116 				usage("sklgT");
117 				exit(255);
118 		}
119 	}
120 
121 	gopt.is_no_encryption = 1;	// Do not use end-2-end encryption
122 	gopt.is_blocking = 1;		// Use blocking sockets
123 
124 	init_vars();			/* from utils.c */
125 
126 	VLOG("=Encryption: %s (Prime: %d bits)\n", GS_get_cipher(gopt.gsocket), GS_get_cipher_strength(gopt.gsocket));
127 }
128 
129 int
main(int argc,char * argv[])130 main(int argc, char *argv[])
131 {
132 	init_defaults(&argc, &argv);
133 	my_getopt(argc, argv);
134 
135 	if (gopt.flags & GSC_FL_IS_SERVER)
136 		do_server();
137 	else
138 		do_client();
139 
140 
141 	exit(255);
142 	return -1;	/* NOT REACHED */
143 }
144