blob: 64d3b49252ae4b3d4000250d55ee0fab582f2874 [file] [log] [blame]
Dave Barachfb5b2af2017-04-17 15:56:17 -04001/*
2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <stdio.h>
17#include <sys/types.h>
18#include <sys/socket.h>
19#include <netinet/in.h>
20#include <netdb.h>
21#include <vppinfra/format.h>
22#include <signal.h>
23#include <sys/ucontext.h>
24
25volatile int signal_received;
26
27static void
28unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
29{
30 signal_received = 1;
31}
32
33static void
34setup_signal_handler (void)
35{
36 uword i;
37 struct sigaction sa;
38
39 for (i = 1; i < 32; i++)
40 {
41 memset (&sa, 0, sizeof (sa));
42 sa.sa_sigaction = (void *) unix_signal_handler;
43 sa.sa_flags = SA_SIGINFO;
44
45 switch (i)
46 {
47 /* these signals take the default action */
48 case SIGABRT:
49 case SIGKILL:
50 case SIGSTOP:
51 case SIGUSR1:
52 case SIGUSR2:
53 continue;
54
55 /* ignore SIGPIPE, SIGCHLD */
56 case SIGPIPE:
57 case SIGCHLD:
58 sa.sa_sigaction = (void *) SIG_IGN;
59 break;
60
61 /* catch and handle all other signals */
62 default:
63 break;
64 }
65
66 if (sigaction (i, &sa, 0) < 0)
67 clib_unix_warning ("sigaction %U", format_signal, i);
68 }
69}
70
71
72int
73main (int argc, char *argv[])
74{
75 int sockfd, portno, n, sent, accfd;
76 struct sockaddr_in serv_addr;
77 struct hostent *server;
78 u8 *rx_buffer = 0;
79
80 if (0 && argc < 3)
81 {
82 fformat (stderr, "usage %s hostname port\n", argv[0]);
83 exit (0);
84 }
85
86 setup_signal_handler ();
87
88 portno = 1234; // atoi(argv[2]);
89 sockfd = socket (AF_INET, SOCK_STREAM, 0);
90 if (sockfd < 0)
91 {
92 clib_unix_error ("socket");
93 exit (1);
94 }
95 server = gethostbyname ("6.0.1.1");
96 if (server == NULL)
97 {
98 clib_unix_warning ("gethostbyname");
99 exit (1);
100 }
101 bzero ((char *) &serv_addr, sizeof (serv_addr));
102 serv_addr.sin_family = AF_INET;
103 bcopy ((char *) server->h_addr,
104 (char *) &serv_addr.sin_addr.s_addr, server->h_length);
105 serv_addr.sin_port = htons (portno);
106 if (bind (sockfd, (const void *) &serv_addr, sizeof (serv_addr)) < 0)
107 {
108 clib_unix_warning ("bind");
109 exit (1);
110 }
111
112 vec_validate (rx_buffer, 8999 /* jumbo mtu */ );
113
114 if (listen (sockfd, 5 /* backlog */ ) < 0)
115 {
116 clib_unix_warning ("listen");
117 close (sockfd);
118 return 1;
119 }
120
121 while (1)
122 {
123 if (signal_received)
124 break;
125
126 accfd = accept (sockfd, 0 /* don't care */ , 0);
127 if (accfd < 0)
128 {
129 clib_unix_warning ("accept");
130 continue;
131 }
132 while (1)
133 {
134 n = recv (accfd, rx_buffer, vec_len (rx_buffer), 0 /* flags */ );
135 if (n == 0)
136 {
137 /* Graceful exit */
138 close (accfd);
139 break;
140 }
141 if (n < 0)
142 {
143 clib_unix_warning ("recv");
144 close (accfd);
145 break;
146 }
147
148 if (signal_received)
149 break;
150
151 sent = send (accfd, rx_buffer, n, 0 /* flags */ );
152 if (n < 0)
153 {
154 clib_unix_warning ("send");
155 close (accfd);
156 break;
157 }
158
159 if (sent != n)
160 {
161 clib_warning ("sent %d not %d", sent, n);
162 }
163
164 if (signal_received)
165 break;
166 }
167 }
168
169 close (sockfd);
170
171 return 0;
172}
173
174
175/*
176 * fd.io coding-style-patch-verification: ON
177 *
178 * Local Variables:
179 * eval: (c-set-style "gnu")
180 * End:
181 */