VPP-659 TCP improvements
[vpp.git] / src / vnet / udp / builtin_server.c
1 /*
2  * Copyright (c) 2016 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 /** @file
17     udp builtin server
18 */
19
20 #include <vnet/udp/udp.h>
21 #include <vnet/session/session.h>
22 #include <vnet/session/application_interface.h>
23
24 /** per-worker built-in server copy buffers */
25 u8 **copy_buffers;
26
27 static int
28 builtin_session_create_callback (stream_session_t * s)
29 {
30   /* Simple version: declare session ready-to-go... */
31   s->session_state = SESSION_STATE_READY;
32   return 0;
33 }
34
35 static void
36 builtin_session_disconnect_callback (stream_session_t * s)
37 {
38   stream_session_disconnect (s);
39 }
40
41 static int
42 builtin_server_rx_callback (stream_session_t * s, session_fifo_event_t * ep)
43 {
44   svm_fifo_t *rx_fifo, *tx_fifo;
45   u32 this_transfer;
46   int actual_transfer;
47   u8 *my_copy_buffer;
48   session_fifo_event_t evt;
49   unix_shared_memory_queue_t *q;
50
51   my_copy_buffer = copy_buffers[s->thread_index];
52   rx_fifo = s->server_rx_fifo;
53   tx_fifo = s->server_tx_fifo;
54
55   this_transfer = svm_fifo_max_enqueue (tx_fifo)
56     < svm_fifo_max_dequeue (rx_fifo) ?
57     svm_fifo_max_enqueue (tx_fifo) : svm_fifo_max_dequeue (rx_fifo);
58
59   vec_validate (my_copy_buffer, this_transfer - 1);
60   _vec_len (my_copy_buffer) = this_transfer;
61
62   actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, 0, this_transfer,
63                                              my_copy_buffer);
64   ASSERT (actual_transfer == this_transfer);
65   actual_transfer = svm_fifo_enqueue_nowait (tx_fifo, 0, this_transfer,
66                                              my_copy_buffer);
67
68   copy_buffers[s->thread_index] = my_copy_buffer;
69
70   /* Fabricate TX event, send to ourselves */
71   evt.fifo = tx_fifo;
72   evt.event_type = FIFO_EVENT_SERVER_TX;
73   /* $$$$ for event logging */
74   evt.enqueue_length = actual_transfer;
75   evt.event_id = 0;
76   q = session_manager_get_vpp_event_queue (s->thread_index);
77   unix_shared_memory_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
78
79   return 0;
80 }
81
82 /* *INDENT-OFF* */
83 static session_cb_vft_t builtin_server = {
84     .session_accept_callback = builtin_session_create_callback,
85     .session_disconnect_callback = builtin_session_disconnect_callback,
86     .builtin_server_rx_callback = builtin_server_rx_callback
87 };
88 /* *INDENT-ON* */
89
90 static int
91 bind_builtin_uri_server (u8 * uri)
92 {
93   vnet_bind_args_t _a, *a = &_a;
94   char segment_name[128];
95   u32 segment_name_length;
96   int rv;
97   u64 options[16];
98
99   segment_name_length = ARRAY_LEN (segment_name);
100
101   memset (a, 0, sizeof (*a));
102   memset (options, 0, sizeof (options));
103
104   a->uri = (char *) uri;
105   a->api_client_index = ~0;     /* built-in server */
106   a->segment_name = segment_name;
107   a->segment_name_length = segment_name_length;
108   a->session_cb_vft = &builtin_server;
109
110   options[SESSION_OPTIONS_ACCEPT_COOKIE] = 0x12345678;
111   options[SESSION_OPTIONS_SEGMENT_SIZE] = (2 << 30);    /*$$$$ config / arg */
112   a->options = options;
113
114   rv = vnet_bind_uri (a);
115
116   return rv;
117 }
118
119 static int
120 unbind_builtin_uri_server (u8 * uri)
121 {
122   int rv;
123
124   rv = vnet_unbind_uri ((char *) uri, ~0 /* client_index */ );
125
126   return rv;
127 }
128
129 static clib_error_t *
130 builtin_server_init (vlib_main_t * vm)
131 {
132   vlib_thread_main_t *vtm = vlib_get_thread_main ();
133   u32 num_threads;
134
135   num_threads = 1 /* main thread */  + vtm->n_threads;
136
137   vec_validate (copy_buffers, num_threads - 1);
138   return 0;
139 }
140
141 VLIB_INIT_FUNCTION (builtin_server_init);
142
143 static clib_error_t *
144 builtin_uri_bind_command_fn (vlib_main_t * vm,
145                              unformat_input_t * input,
146                              vlib_cli_command_t * cmd)
147 {
148   u8 *uri = 0;
149   int rv;
150
151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
152     {
153       if (unformat (input, "uri %s", &uri))
154         ;
155       else
156         break;
157     }
158
159   if (uri == 0)
160     return clib_error_return (0, "uri to bind not specified...");
161
162   rv = bind_builtin_uri_server (uri);
163
164   vec_free (uri);
165
166   switch (rv)
167     {
168     case 0:
169       break;
170
171     default:
172       return clib_error_return (0, "bind_uri_server returned %d", rv);
173       break;
174     }
175
176   return 0;
177 }
178
179 /* *INDENT-OFF* */
180 VLIB_CLI_COMMAND (builtin_uri_bind_command, static) =
181 {
182   .path = "builtin uri bind",
183   .short_help = "builtin uri bind",
184   .function = builtin_uri_bind_command_fn,
185 };
186 /* *INDENT-ON* */
187
188 static clib_error_t *
189 builtin_uri_unbind_command_fn (vlib_main_t * vm,
190                                unformat_input_t * input,
191                                vlib_cli_command_t * cmd)
192 {
193   u8 *uri = 0;
194   int rv;
195
196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
197     {
198       if (unformat (input, "uri %s", &uri))
199         ;
200       else
201         break;
202     }
203
204   if (uri == 0)
205     return clib_error_return (0, "uri to unbind not specified...");
206
207   rv = unbind_builtin_uri_server (uri);
208
209   vec_free (uri);
210
211   switch (rv)
212     {
213     case 0:
214       break;
215
216     default:
217       return clib_error_return (0, "unbind_uri_server returned %d", rv);
218       break;
219     }
220
221   return 0;
222 }
223
224 /* *INDENT-OFF* */
225 VLIB_CLI_COMMAND (builtin_uri_unbind_command, static) =
226 {
227   .path = "builtin uri unbind",
228   .short_help = "builtin uri unbind",
229   .function = builtin_uri_unbind_command_fn,
230 };
231 /* *INDENT-ON* */
232
233 /*
234  * fd.io coding-style-patch-verification: ON
235  *
236  * Local Variables:
237  * eval: (c-set-style "gnu")
238  * End:
239  */