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