FD.io VPP  v21.06
Vector Packet Processing
proxy.c
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2017-2019 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 <vnet/vnet.h>
17 #include <vlibmemory/api.h>
20 #include <hs_apps/proxy.h>
21 #include <vnet/tcp/tcp.h>
22 
24 
25 #define TCP_MSS 1460
26 
27 typedef struct
28 {
33 
34 static void
36 {
39 
40  clib_memset (&a, 0, sizeof (a));
41  a.api_context = pa->api_context;
42  a.app_index = pa->app_index;
43  clib_memcpy (&a.sep_ext, &pa->sep, sizeof (pa->sep));
44  vnet_connect (&a);
45  if (a.sep_ext.ext_cfg)
46  clib_mem_free (a.sep_ext.ext_cfg);
47 }
48 
49 static void
51 {
52  if (vlib_get_thread_index () == 0)
53  {
54  vnet_connect (a);
55  if (a->sep_ext.ext_cfg)
56  clib_mem_free (a->sep_ext.ext_cfg);
57  }
58  else
59  {
61  args.api_context = a->api_context;
62  args.app_index = a->app_index;
63  clib_memcpy (&args.sep, &a->sep_ext, sizeof (a->sep_ext));
64  vl_api_rpc_call_main_thread (proxy_cb_fn, (u8 *) & args, sizeof (args));
65  }
66 }
67 
68 static proxy_session_t *
70 {
71  proxy_session_t *ps = 0;
72  uword *p;
73 
75  if (p)
76  ps = pool_elt_at_index (pm->sessions, p[0]);
77  return ps;
78 }
79 
80 static proxy_session_t *
82 {
83  proxy_session_t *ps = 0;
84  uword *p;
85 
86  p = hash_get (pm->proxy_session_by_server_handle, handle);
87  if (p)
88  ps = pool_elt_at_index (pm->sessions, p[0]);
89  return ps;
90 }
91 
92 static void
93 proxy_try_close_session (session_t * s, int is_active_open)
94 {
95  proxy_main_t *pm = &proxy_main;
96  proxy_session_t *ps = 0;
97  vnet_disconnect_args_t _a, *a = &_a;
98  session_handle_t handle;
99 
100  handle = session_handle (s);
101 
103 
104  if (is_active_open)
105  {
106  ps = proxy_get_active_open (pm, handle);
107  ASSERT (ps != 0);
108 
109  a->handle = ps->vpp_active_open_handle;
110  a->app_index = pm->active_open_app_index;
112  ps->ao_disconnected = 1;
113 
114  if (!ps->po_disconnected)
115  {
117  a->handle = ps->vpp_server_handle;
118  a->app_index = pm->server_app_index;
120  ps->po_disconnected = 1;
121  }
122  }
123  else
124  {
125  ps = proxy_get_passive_open (pm, handle);
126  ASSERT (ps != 0);
127 
128  a->handle = ps->vpp_server_handle;
129  a->app_index = pm->server_app_index;
131  ps->po_disconnected = 1;
132 
133  if (!ps->ao_disconnected && !ps->active_open_establishing)
134  {
135  /* Proxy session closed before active open */
137  {
138  a->handle = ps->vpp_active_open_handle;
139  a->app_index = pm->active_open_app_index;
141  }
142  ps->ao_disconnected = 1;
143  }
144  }
146 }
147 
148 static void
150 {
151  proxy_main_t *pm = &proxy_main;
152  if (CLIB_DEBUG > 0)
153  clib_memset (ps, 0xFE, sizeof (*ps));
154  pool_put (pm->sessions, ps);
155 }
156 
157 static void
158 proxy_try_delete_session (session_t * s, u8 is_active_open)
159 {
160  proxy_main_t *pm = &proxy_main;
161  proxy_session_t *ps = 0;
162  session_handle_t handle;
163 
164  handle = session_handle (s);
165 
167 
168  if (is_active_open)
169  {
170  ps = proxy_get_active_open (pm, handle);
171  ASSERT (ps != 0);
172 
175 
177  proxy_session_free (ps);
178  }
179  else
180  {
181  ps = proxy_get_passive_open (pm, handle);
182  ASSERT (ps != 0);
183 
186 
188  {
189  if (!ps->active_open_establishing)
190  proxy_session_free (ps);
191  }
192  }
194 }
195 
196 static int
198  session_ft_action_t act, u32 bytes)
199 {
200  proxy_main_t *pm = &proxy_main;
201 
202  segment_manager_t *sm = segment_manager_get (f->segment_manager);
203  fifo_segment_t *fs = segment_manager_get_segment (sm, f->segment_index);
204 
205  u8 seg_usage = fifo_segment_get_mem_usage (fs);
206  u32 fifo_in_use = svm_fifo_max_dequeue_prod (f);
207  u32 fifo_size = svm_fifo_size (f);
208  u8 fifo_usage = fifo_in_use * 100 / fifo_size;
209  u8 update_size = 0;
210 
212 
213  if (act == SESSION_FT_ACTION_ENQUEUED)
214  {
215  if (seg_usage < pm->low_watermark && fifo_usage > 50)
216  update_size = fifo_in_use;
217  else if (seg_usage < pm->high_watermark && fifo_usage > 80)
218  update_size = fifo_in_use;
219 
220  update_size = clib_min (update_size, sm->max_fifo_size - fifo_size);
221  if (update_size)
222  svm_fifo_set_size (f, fifo_size + update_size);
223  }
224  else /* dequeued */
225  {
226  if (seg_usage > pm->high_watermark || fifo_usage < 20)
227  update_size = bytes;
228  else if (seg_usage > pm->low_watermark && fifo_usage < 50)
229  update_size = (bytes / 2);
230 
231  ASSERT (fifo_size >= 4096);
232  update_size = clib_min (update_size, fifo_size - 4096);
233  if (update_size)
234  svm_fifo_set_size (f, fifo_size - update_size);
235  }
236 
237  return 0;
238 }
239 
240 static int
242 {
243  proxy_main_t *pm = &proxy_main;
244  proxy_session_t *ps;
245 
247 
248  pool_get_zero (pm->sessions, ps);
251 
253  ps - pm->sessions);
254 
256 
257  s->session_state = SESSION_STATE_READY;
258 
259  return 0;
260 }
261 
262 static void
264 {
265  proxy_try_close_session (s, 0 /* is_active_open */ );
266 }
267 
268 static void
270 {
271  proxy_try_close_session (s, 0 /* is_active_open */ );
272 }
273 
274 static int
275 proxy_connected_callback (u32 app_index, u32 api_context,
276  session_t * s, session_error_t err)
277 {
278  clib_warning ("called...");
279  return -1;
280 }
281 
282 static int
283 proxy_add_segment_callback (u32 client_index, u64 segment_handle)
284 {
285  return 0;
286 }
287 
288 static int
290 {
291  return proto == TRANSPORT_PROTO_TLS;
292 }
293 
294 static int
296 {
297  proxy_main_t *pm = &proxy_main;
299  svm_fifo_t *ao_tx_fifo;
300  proxy_session_t *ps;
301 
302  ASSERT (s->thread_index == thread_index);
303 
305 
306  ps = proxy_get_passive_open (pm, session_handle (s));
307  ASSERT (ps != 0);
308 
310  {
312 
313  ao_tx_fifo = s->rx_fifo;
314 
315  /*
316  * Send event for active open tx fifo
317  */
318  if (svm_fifo_set_event (ao_tx_fifo))
319  {
320  u32 ao_thread_index = ao_tx_fifo->master_thread_index;
321  u32 ao_session_index = ao_tx_fifo->shr->master_session_index;
322  if (session_send_io_evt_to_thread_custom (&ao_session_index,
323  ao_thread_index,
325  clib_warning ("failed to enqueue tx evt");
326  }
327 
328  if (svm_fifo_max_enqueue (ao_tx_fifo) <= TCP_MSS)
330  }
331  else
332  {
333  vnet_connect_args_t _a, *a = &_a;
334  svm_fifo_t *tx_fifo, *rx_fifo;
335  u32 max_dequeue, proxy_index;
336  int actual_transfer __attribute__ ((unused));
337 
338  rx_fifo = s->rx_fifo;
339  tx_fifo = s->tx_fifo;
340 
341  ASSERT (rx_fifo->master_thread_index == thread_index);
342  ASSERT (tx_fifo->master_thread_index == thread_index);
343 
344  max_dequeue = svm_fifo_max_dequeue_cons (s->rx_fifo);
345 
346  if (PREDICT_FALSE (max_dequeue == 0))
347  return 0;
348 
349  max_dequeue = clib_min (pm->rcv_buffer_size, max_dequeue);
350  actual_transfer = svm_fifo_peek (rx_fifo, 0 /* relative_offset */ ,
351  max_dequeue, pm->rx_buf[thread_index]);
352 
353  /* $$$ your message in this space: parse url, etc. */
354 
355  clib_memset (a, 0, sizeof (*a));
356 
357  ps->server_rx_fifo = rx_fifo;
358  ps->server_tx_fifo = tx_fifo;
359  ps->active_open_establishing = 1;
360  proxy_index = ps - pm->sessions;
361 
363 
364  clib_memcpy (&a->sep_ext, &pm->client_sep, sizeof (pm->client_sep));
365  a->api_context = proxy_index;
366  a->app_index = pm->active_open_app_index;
367 
368  if (proxy_transport_needs_crypto (a->sep.transport_proto))
369  {
370  session_endpoint_alloc_ext_cfg (&a->sep_ext,
372  a->sep_ext.ext_cfg->crypto.ckpair_index = pm->ckpair_index;
373  }
374 
376  }
377 
378  return 0;
379 }
380 
381 static void
382 proxy_force_ack (void *handlep)
383 {
385  session_t *ao_s;
386 
387  ao_s = session_get_from_handle (pointer_to_uword (handlep));
388  if (session_get_transport_proto (ao_s) != TRANSPORT_PROTO_TCP)
389  return;
390  tc = session_get_transport (ao_s);
392 }
393 
394 static int
396 {
397  proxy_main_t *pm = &proxy_main;
398  proxy_session_t *ps;
399  u32 min_free;
400 
401  min_free = clib_min (svm_fifo_size (proxy_s->tx_fifo) >> 3, 128 << 10);
402  if (svm_fifo_max_enqueue (proxy_s->tx_fifo) < min_free)
403  {
405  return 0;
406  }
407 
409 
410  ps = proxy_get_passive_open (pm, session_handle (proxy_s));
411  ASSERT (ps != 0);
412 
414  return 0;
415 
416  /* Force ack on active open side to update rcv wnd. Make sure it's done on
417  * the right thread */
418  void *arg = uword_to_pointer (ps->vpp_active_open_handle, void *);
419  session_send_rpc_evt_to_thread (ps->server_rx_fifo->master_thread_index,
420  proxy_force_ack, arg);
421 
423 
424  return 0;
425 }
426 
427 static void
429 {
430  if (ntf == SESSION_CLEANUP_TRANSPORT)
431  return;
432 
433  proxy_try_delete_session (s, 0 /* is_active_open */ );
434 }
435 
436 static session_cb_vft_t proxy_session_cb_vft = {
438  .session_disconnect_callback = proxy_disconnect_callback,
439  .session_connected_callback = proxy_connected_callback,
440  .add_segment_callback = proxy_add_segment_callback,
441  .builtin_app_rx_callback = proxy_rx_callback,
442  .builtin_app_tx_callback = proxy_tx_callback,
443  .session_reset_callback = proxy_reset_callback,
444  .session_cleanup_callback = proxy_cleanup_callback,
445  .fifo_tuning_callback = common_fifo_tuning_callback
446 };
447 
448 static int
450  session_t * s, session_error_t err)
451 {
452  proxy_main_t *pm = &proxy_main;
453  proxy_session_t *ps;
455 
456  /*
457  * Setup proxy session handle.
458  */
460 
461  ps = pool_elt_at_index (pm->sessions, opaque);
462 
463  /* Connection failed */
464  if (err)
465  {
466  vnet_disconnect_args_t _a, *a = &_a;
467 
468  a->handle = ps->vpp_server_handle;
469  a->app_index = pm->server_app_index;
471  ps->po_disconnected = 1;
472  }
473  else
474  {
476  ps->active_open_establishing = 0;
477  }
478 
479  /* Passive open session was already closed! */
480  if (ps->po_disconnected)
481  {
482  /* Setup everything for the cleanup notification */
484  ps->vpp_active_open_handle, opaque);
485  ps->ao_disconnected = 1;
487  return -1;
488  }
489 
490  s->tx_fifo = ps->server_rx_fifo;
491  s->rx_fifo = ps->server_tx_fifo;
492 
493  /*
494  * Reset the active-open tx-fifo master indices so the active-open session
495  * will receive data, etc.
496  */
497  s->tx_fifo->shr->master_session_index = s->session_index;
498  s->tx_fifo->master_thread_index = s->thread_index;
499 
500  /*
501  * Account for the active-open session's use of the fifos
502  * so they won't disappear until the last session which uses
503  * them disappears
504  */
505  s->tx_fifo->refcnt++;
506  s->rx_fifo->refcnt++;
507 
509  ps->vpp_active_open_handle, opaque);
510 
512 
513  /*
514  * Send event for active open tx fifo
515  */
516  ASSERT (s->thread_index == thread_index);
517  if (svm_fifo_set_event (s->tx_fifo))
519 
520  return 0;
521 }
522 
523 static void
525 {
526  proxy_try_close_session (s, 1 /* is_active_open */ );
527 }
528 
529 static int
531 {
532  return 0;
533 }
534 
535 static void
537 {
538  proxy_try_close_session (s, 1 /* is_active_open */ );
539 }
540 
541 static int
543 {
544  svm_fifo_t *proxy_tx_fifo;
545 
546  proxy_tx_fifo = s->rx_fifo;
547 
548  /*
549  * Send event for server tx fifo
550  */
551  if (svm_fifo_set_event (proxy_tx_fifo))
552  {
553  u8 thread_index = proxy_tx_fifo->master_thread_index;
554  u32 session_index = proxy_tx_fifo->shr->master_session_index;
555  return session_send_io_evt_to_thread_custom (&session_index,
556  thread_index,
558  }
559 
560  if (svm_fifo_max_enqueue (proxy_tx_fifo) <= TCP_MSS)
562 
563  return 0;
564 }
565 
566 static int
568 {
569  proxy_main_t *pm = &proxy_main;
571  session_handle_t handle;
572  proxy_session_t *ps;
573  session_t *proxy_s;
574  u32 min_free;
575  uword *p;
576 
577  min_free = clib_min (svm_fifo_size (ao_s->tx_fifo) >> 3, 128 << 10);
578  if (svm_fifo_max_enqueue (ao_s->tx_fifo) < min_free)
579  {
581  return 0;
582  }
583 
585 
586  handle = session_handle (ao_s);
588  if (!p)
589  return 0;
590 
591  if (pool_is_free_index (pm->sessions, p[0]))
592  return 0;
593 
594  ps = pool_elt_at_index (pm->sessions, p[0]);
595  if (ps->vpp_server_handle == ~0)
596  return 0;
597 
599 
600  /* Force ack on proxy side to update rcv wnd */
601  tc = session_get_transport (proxy_s);
603 
605 
606  return 0;
607 }
608 
609 static void
611 {
612  if (ntf == SESSION_CLEANUP_TRANSPORT)
613  return;
614 
615  proxy_try_delete_session (s, 1 /* is_active_open */ );
616 }
617 
618 /* *INDENT-OFF* */
619 static session_cb_vft_t active_open_clients = {
621  .session_connected_callback = active_open_connected_callback,
622  .session_accept_callback = active_open_create_callback,
623  .session_disconnect_callback = active_open_disconnect_callback,
624  .session_cleanup_callback = active_open_cleanup_callback,
625  .builtin_app_rx_callback = active_open_rx_callback,
626  .builtin_app_tx_callback = active_open_tx_callback,
627  .fifo_tuning_callback = common_fifo_tuning_callback
628 };
629 /* *INDENT-ON* */
630 
631 static int
633 {
634  proxy_main_t *pm = &proxy_main;
636  vnet_app_attach_args_t _a, *a = &_a;
637  u32 segment_size = 512 << 20;
638 
639  clib_memset (a, 0, sizeof (*a));
640  clib_memset (options, 0, sizeof (options));
641 
642  if (pm->private_segment_size)
643  segment_size = pm->private_segment_size;
644  a->name = format (0, "proxy-server");
645  a->api_client_index = pm->server_client_index;
646  a->session_cb_vft = &proxy_session_cb_vft;
647  a->options = options;
648  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
649  a->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = segment_size;
650  a->options[APP_OPTIONS_RX_FIFO_SIZE] = pm->fifo_size;
651  a->options[APP_OPTIONS_TX_FIFO_SIZE] = pm->fifo_size;
652  a->options[APP_OPTIONS_MAX_FIFO_SIZE] = pm->max_fifo_size;
653  a->options[APP_OPTIONS_HIGH_WATERMARK] = (u64) pm->high_watermark;
654  a->options[APP_OPTIONS_LOW_WATERMARK] = (u64) pm->low_watermark;
656  a->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
657  pm->prealloc_fifos ? pm->prealloc_fifos : 0;
658 
659  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
660 
661  if (vnet_application_attach (a))
662  {
663  clib_warning ("failed to attach server");
664  return -1;
665  }
666  pm->server_app_index = a->app_index;
667 
668  vec_free (a->name);
669  return 0;
670 }
671 
672 static int
674 {
675  proxy_main_t *pm = &proxy_main;
676  vnet_app_attach_args_t _a, *a = &_a;
678 
679  clib_memset (a, 0, sizeof (*a));
680  clib_memset (options, 0, sizeof (options));
681 
682  a->api_client_index = pm->active_open_client_index;
683  a->session_cb_vft = &active_open_clients;
684  a->name = format (0, "proxy-active-open");
685 
686  options[APP_OPTIONS_ACCEPT_COOKIE] = 0x12345678;
687  options[APP_OPTIONS_SEGMENT_SIZE] = 512 << 20;
688  options[APP_OPTIONS_RX_FIFO_SIZE] = pm->fifo_size;
689  options[APP_OPTIONS_TX_FIFO_SIZE] = pm->fifo_size;
695  pm->prealloc_fifos ? pm->prealloc_fifos : 0;
696 
697  options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN
698  | APP_OPTIONS_FLAGS_IS_PROXY;
699 
700  a->options = options;
701 
702  if (vnet_application_attach (a))
703  return -1;
704 
705  pm->active_open_app_index = a->app_index;
706 
707  vec_free (a->name);
708 
709  return 0;
710 }
711 
712 static int
714 {
715  proxy_main_t *pm = &proxy_main;
716  vnet_listen_args_t _a, *a = &_a;
717  int rv;
718 
719  clib_memset (a, 0, sizeof (*a));
720 
721  a->app_index = pm->server_app_index;
722  clib_memcpy (&a->sep_ext, &pm->server_sep, sizeof (pm->server_sep));
723  if (proxy_transport_needs_crypto (a->sep.transport_proto))
724  {
725  session_endpoint_alloc_ext_cfg (&a->sep_ext,
727  a->sep_ext.ext_cfg->crypto.ckpair_index = pm->ckpair_index;
728  }
729 
730  rv = vnet_listen (a);
731  if (a->sep_ext.ext_cfg)
732  clib_mem_free (a->sep_ext.ext_cfg);
733 
734  return rv;
735 }
736 
737 static void
739 {
740  vnet_app_add_cert_key_pair_args_t _ck_pair, *ck_pair = &_ck_pair;
741  proxy_main_t *pm = &proxy_main;
742 
743  clib_memset (ck_pair, 0, sizeof (*ck_pair));
744  ck_pair->cert = (u8 *) test_srv_crt_rsa;
745  ck_pair->key = (u8 *) test_srv_key_rsa;
746  ck_pair->cert_len = test_srv_crt_rsa_len;
747  ck_pair->key_len = test_srv_key_rsa_len;
748  vnet_app_add_cert_key_pair (ck_pair);
749 
750  pm->ckpair_index = ck_pair->index;
751 }
752 
753 static int
755 {
756  proxy_main_t *pm = &proxy_main;
758  u32 num_threads;
759  int i;
760 
761  num_threads = 1 /* main thread */ + vtm->n_threads;
762  vec_validate (proxy_main.server_event_queue, num_threads - 1);
763  vec_validate (proxy_main.active_open_event_queue, num_threads - 1);
764  vec_validate (pm->rx_buf, num_threads - 1);
765 
766  for (i = 0; i < num_threads; i++)
767  vec_validate (pm->rx_buf[i], pm->rcv_buffer_size);
768 
770 
771  if (proxy_server_attach ())
772  {
773  clib_warning ("failed to attach server app");
774  return -1;
775  }
776  if (proxy_server_listen ())
777  {
778  clib_warning ("failed to start listening");
779  return -1;
780  }
781  if (active_open_attach ())
782  {
783  clib_warning ("failed to attach active open app");
784  return -1;
785  }
786 
787  for (i = 0; i < num_threads; i++)
788  {
790 
792 
794  }
795 
796  return 0;
797 }
798 
799 static clib_error_t *
801  vlib_cli_command_t * cmd)
802 {
803  unformat_input_t _line_input, *line_input = &_line_input;
804  char *default_server_uri = "tcp://0.0.0.0/23";
805  char *default_client_uri = "tcp://6.0.2.2/23";
806  u8 *server_uri = 0, *client_uri = 0;
807  proxy_main_t *pm = &proxy_main;
808  clib_error_t *error = 0;
809  int rv, tmp32;
810  u64 tmp64;
811 
812  pm->fifo_size = 64 << 10;
813  pm->max_fifo_size = 128 << 20;
814  pm->high_watermark = 80;
815  pm->low_watermark = 50;
816  pm->rcv_buffer_size = 1024;
817  pm->prealloc_fifos = 0;
818  pm->private_segment_count = 0;
819  pm->private_segment_size = 0;
820 
821  if (vlib_num_workers ())
823 
824  if (!unformat_user (input, unformat_line_input, line_input))
825  return 0;
826 
827  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
828  {
829  if (unformat (line_input, "fifo-size %U", unformat_memory_size,
830  &pm->fifo_size))
831  ;
832  else if (unformat (line_input, "max-fifo-size %U", unformat_memory_size,
833  &pm->max_fifo_size))
834  ;
835  else if (unformat (line_input, "high-watermark %d", &tmp32))
836  pm->high_watermark = (u8) tmp32;
837  else if (unformat (line_input, "low-watermark %d", &tmp32))
838  pm->low_watermark = (u8) tmp32;
839  else if (unformat (line_input, "rcv-buf-size %d", &pm->rcv_buffer_size))
840  ;
841  else if (unformat (line_input, "prealloc-fifos %d", &pm->prealloc_fifos))
842  ;
843  else if (unformat (line_input, "private-segment-count %d",
844  &pm->private_segment_count))
845  ;
846  else if (unformat (line_input, "private-segment-size %U",
847  unformat_memory_size, &tmp64))
848  {
849  if (tmp64 >= 0x100000000ULL)
850  {
851  error = clib_error_return (
852  0, "private segment size %lld (%llu) too large", tmp64, tmp64);
853  goto done;
854  }
855  pm->private_segment_size = tmp64;
856  }
857  else if (unformat (line_input, "server-uri %s", &server_uri))
858  vec_add1 (server_uri, 0);
859  else if (unformat (line_input, "client-uri %s", &client_uri))
860  vec_add1 (client_uri, 0);
861  else
862  {
863  error = clib_error_return (0, "unknown input `%U'",
864  format_unformat_error, line_input);
865  goto done;
866  }
867  }
868 
869  if (!server_uri)
870  {
871  clib_warning ("No server-uri provided, Using default: %s",
872  default_server_uri);
873  server_uri = format (0, "%s%c", default_server_uri, 0);
874  }
875  if (!client_uri)
876  {
877  clib_warning ("No client-uri provided, Using default: %s",
878  default_client_uri);
879  client_uri = format (0, "%s%c", default_client_uri, 0);
880  }
881 
882  if (parse_uri ((char *) server_uri, &pm->server_sep))
883  {
884  error = clib_error_return (0, "Invalid server uri %v", server_uri);
885  goto done;
886  }
887  if (parse_uri ((char *) client_uri, &pm->client_sep))
888  {
889  error = clib_error_return (0, "Invalid client uri %v", client_uri);
890  goto done;
891  }
892 
893  vnet_session_enable_disable (vm, 1 /* turn on session and transport */ );
894 
895  rv = proxy_server_create (vm);
896  switch (rv)
897  {
898  case 0:
899  break;
900  default:
901  error = clib_error_return (0, "server_create returned %d", rv);
902  }
903 
904 done:
905  unformat_free (line_input);
906  vec_free (client_uri);
907  vec_free (server_uri);
908  return error;
909 }
910 
911 /* *INDENT-OFF* */
912 VLIB_CLI_COMMAND (proxy_create_command, static) =
913 {
914  .path = "test proxy server",
915  .short_help = "test proxy server [server-uri <tcp://ip/port>]"
916  "[client-uri <tcp://ip/port>][fifo-size <nn>[k|m]]"
917  "[max-fifo-size <nn>[k|m]][high-watermark <nn>]"
918  "[low-watermark <nn>][rcv-buf-size <nn>][prealloc-fifos <nn>]"
919  "[private-segment-size <mem>][private-segment-count <nn>]",
920  .function = proxy_server_create_command_fn,
921 };
922 /* *INDENT-ON* */
923 
924 clib_error_t *
926 {
927  proxy_main_t *pm = &proxy_main;
928  pm->server_client_index = ~0;
929  pm->active_open_client_index = ~0;
932 
933  return 0;
934 }
935 
937 
938 /*
939 * fd.io coding-style-patch-verification: ON
940 *
941 * Local Variables:
942 * eval: (c-set-style "gnu")
943 * End:
944 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
#define hash_set(h, key, value)
Definition: hash.h:255
u32 max_fifo_size
max fifo size
Definition: proxy.h:64
#define clib_min(x, y)
Definition: clib.h:342
u32 private_segment_count
Number of private fifo segs.
Definition: proxy.h:67
volatile int ao_disconnected
Definition: proxy.h:38
int vnet_app_add_cert_key_pair(vnet_app_add_cert_key_pair_args_t *a)
Definition: application.c:2017
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:544
static void svm_fifo_set_size(svm_fifo_t *f, u32 size)
Definition: svm_fifo.h:760
svm_fifo_t * tx_fifo
struct _vnet_connect_args vnet_connect_args_t
fifo_segment_t * segment_manager_get_segment(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager&#39;s pool without lock.
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
Notify on dequeue.
Definition: svm_fifo.h:35
static u32 svm_fifo_size(svm_fifo_t *f)
Definition: svm_fifo.h:754
u32 thread_index
#define PREDICT_TRUE(x)
Definition: clib.h:125
u32 session_index
Index in thread pool where session was allocated.
static int proxy_accept_callback(session_t *s)
Definition: proxy.c:241
unsigned long u64
Definition: types.h:89
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
Definition: session.h:716
static void proxy_reset_callback(session_t *s)
Definition: proxy.c:269
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
transport_connection_t * session_get_transport(session_t *s)
Definition: session.c:1745
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
u8 fifo_segment_get_mem_usage(fifo_segment_t *fs)
static int active_open_rx_callback(session_t *s)
Definition: proxy.c:542
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:129
static clib_error_t * proxy_server_create_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: proxy.c:800
struct _tcp_connection tcp_connection_t
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
static transport_proto_t session_get_transport_proto(session_t *s)
void session_send_rpc_evt_to_thread(u32 thread_index, void *fp, void *rpc_args)
Definition: session.c:116
int svm_fifo_peek(svm_fifo_t *f, u32 offset, u32 len, u8 *dst)
Peek data from fifo.
Definition: svm_fifo.c:1141
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
uword * proxy_session_by_server_handle
Definition: proxy.h:55
static u32 svm_fifo_max_enqueue(svm_fifo_t *f)
Definition: svm_fifo.h:621
void(* session_reset_callback)(session_t *s)
Notify app that session was reset.
session_endpoint_cfg_t sep
Definition: proxy.c:29
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:92
struct _vnet_bind_args_t vnet_listen_args_t
static int active_open_create_callback(session_t *s)
Definition: proxy.c:530
svm_fifo_t * server_rx_fifo
Definition: proxy.h:31
static session_handle_t session_handle(session_t *s)
unsigned int u32
Definition: types.h:88
#define clib_memcpy(d, s, n)
Definition: string.h:197
vlib_frame_t * f
enum session_ft_action_ session_ft_action_t
session_endpoint_cfg_t client_sep
Definition: proxy.h:71
u8 prealloc_fifos
Request fifo preallocation.
Definition: proxy.h:86
u32 fifo_size
initial fifo size
Definition: proxy.h:63
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
struct _vnet_disconnect_args_t vnet_disconnect_args_t
static const u32 test_srv_key_rsa_len
Definition: tls_test.h:77
static u32 svm_fifo_max_dequeue_cons(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for consumer.
Definition: svm_fifo.h:487
description fragment has unexpected format
Definition: map.api:433
static session_cb_vft_t proxy_session_cb_vft
Definition: proxy.c:436
#define clib_error_return(e, args...)
Definition: error.h:99
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:620
session_handle_t vpp_active_open_handle
Definition: proxy.h:35
int rcv_buffer_size
Definition: proxy.h:69
u32 server_app_index
server app index
Definition: proxy.h:51
static proxy_session_t * proxy_get_active_open(proxy_main_t *pm, session_handle_t handle)
Definition: proxy.c:69
int __clib_unused rv
Definition: application.c:491
int session_send_io_evt_to_thread(svm_fifo_t *f, session_evt_type_t evt_type)
Definition: session.c:84
volatile int active_open_establishing
Definition: proxy.h:36
static int proxy_connected_callback(u32 app_index, u32 api_context, session_t *s, session_error_t err)
Definition: proxy.c:275
#define SESSION_INVALID_HANDLE
Definition: session_types.h:23
struct _vnet_app_attach_args_t vnet_app_attach_args_t
unformat_function_t unformat_line_input
Definition: format.h:275
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
struct _session_endpoint_cfg session_endpoint_cfg_t
static int proxy_tx_callback(session_t *proxy_s)
Definition: proxy.c:395
session_handle_t vpp_server_handle
Definition: proxy.h:34
clib_error_t * proxy_main_init(vlib_main_t *vm)
Definition: proxy.c:925
Definition: cJSON.c:88
static int common_fifo_tuning_callback(session_t *s, svm_fifo_t *f, session_ft_action_t act, u32 bytes)
Definition: proxy.c:197
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
proxy_session_t * sessions
Session pool, shared.
Definition: proxy.h:77
void tcp_send_ack(tcp_connection_t *tc)
Definition: tcp_output.c:1021
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:356
vl_api_ip_proto_t proto
Definition: acl_types.api:51
struct _unformat_input_t unformat_input_t
u8 data_len
Definition: ikev2_types.api:24
static void active_open_disconnect_callback(session_t *s)
Definition: proxy.c:536
static void proxy_cb_fn(void *data, u32 data_len)
Definition: proxy.c:35
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
static int proxy_transport_needs_crypto(transport_proto_t proto)
Definition: proxy.c:289
#define PREDICT_FALSE(x)
Definition: clib.h:124
u8 low_watermark
low watermark (%)
Definition: proxy.h:66
proxy_main_t proxy_main
Definition: proxy.c:23
u32 ckpair_index
Definition: proxy.h:73
static int proxy_server_create(vlib_main_t *vm)
Definition: proxy.c:754
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
static u32 svm_fifo_max_dequeue_prod(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for producer.
Definition: svm_fifo.h:501
static const char test_srv_crt_rsa[]
Definition: tls_test.h:23
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1927
static void session_endpoint_alloc_ext_cfg(session_endpoint_cfg_t *sep_ext, transport_endpt_ext_cfg_type_t type)
int vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
Definition: application.c:1114
static u8 svm_fifo_set_event(svm_fifo_t *f)
Set fifo event flag.
Definition: svm_fifo.h:790
svm_msg_q_t ** active_open_event_queue
Definition: proxy.h:46
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
u32 active_open_client_index
active open API client handle
Definition: proxy.h:52
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:208
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
static int active_open_connected_callback(u32 app_index, u32 opaque, session_t *s, session_error_t err)
Definition: proxy.c:449
static void proxy_server_add_ckpair(void)
Definition: proxy.c:738
#define clib_warning(format, args...)
Definition: error.h:59
u32 server_client_index
server API client handle
Definition: proxy.h:50
struct _transport_connection transport_connection_t
static void proxy_call_main_thread(vnet_connect_args_t *a)
Definition: proxy.c:50
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
#define TCP_MSS
Definition: proxy.c:25
static void active_open_reset_callback(session_t *s)
Definition: proxy.c:524
volatile int po_disconnected
Definition: proxy.h:37
static void proxy_session_free(proxy_session_t *ps)
Definition: proxy.c:149
svm_msg_q_t ** server_event_queue
per-thread vectors
Definition: proxy.h:45
static const char test_srv_key_rsa[]
Definition: tls_test.h:49
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
u32 active_open_app_index
active open index after attach
Definition: proxy.h:53
#define hash_create(elts, value_bytes)
Definition: hash.h:696
#define uword_to_pointer(u, type)
Definition: types.h:136
#define ASSERT(truth)
static int proxy_server_attach()
Definition: proxy.c:632
uword * proxy_session_by_active_open_handle
Definition: proxy.h:56
static int proxy_rx_callback(session_t *s)
Definition: proxy.c:295
int vnet_listen(vnet_listen_args_t *a)
Definition: application.c:1266
u8 ** rx_buf
intermediate rx buffers
Definition: proxy.h:47
static void clib_mem_free(void *p)
Definition: mem.h:311
enum _transport_proto transport_proto_t
static proxy_session_t * proxy_get_passive_open(proxy_main_t *pm, session_handle_t handle)
Definition: proxy.c:81
struct _vnet_app_add_cert_key_pair_args_ vnet_app_add_cert_key_pair_args_t
static void svm_fifo_add_want_deq_ntf(svm_fifo_t *f, u8 ntf_type)
Set specific want notification flag.
Definition: svm_fifo.h:817
clib_spinlock_t sessions_lock
Definition: proxy.h:78
static uword pointer_to_uword(const void *p)
Definition: types.h:131
int vnet_connect(vnet_connect_args_t *a)
Definition: application.c:1320
u8 thread_index
Index of the thread that allocated the session.
u32 private_segment_size
size of private fifo segs
Definition: proxy.h:68
static int active_open_attach(void)
Definition: proxy.c:673
u8 high_watermark
high watermark (%)
Definition: proxy.h:65
int parse_uri(char *uri, session_endpoint_cfg_t *sep)
svm_fifo_t * server_tx_fifo
Definition: proxy.h:32
u64 session_handle_t
static void proxy_disconnect_callback(session_t *s)
Definition: proxy.c:263
volatile u8 session_state
State in session layer state machine.
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
int vnet_disconnect_session(vnet_disconnect_args_t *a)
Definition: application.c:1411
struct _segment_manager segment_manager_t
segment_manager_t * segment_manager_get(u32 index)
static void proxy_force_ack(void *handlep)
Definition: proxy.c:382
session_cleanup_ntf_t
session_endpoint_cfg_t server_sep
Definition: proxy.h:70
int session_send_io_evt_to_thread_custom(void *data, u32 thread_index, session_evt_type_t evt_type)
Definition: session.c:91
static void proxy_try_close_session(session_t *s, int is_active_open)
Definition: proxy.c:93
unformat_function_t unformat_memory_size
Definition: format.h:288
static int proxy_add_segment_callback(u32 client_index, u64 segment_handle)
Definition: proxy.c:283
static struct option options[]
Definition: main.c:52
static int proxy_server_listen()
Definition: proxy.c:713
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
static u32 vlib_num_workers()
Definition: threads.h:354
enum session_error_ session_error_t
static session_cb_vft_t active_open_clients
Definition: proxy.c:619
static int active_open_tx_callback(session_t *ao_s)
Definition: proxy.c:567
int(* session_accept_callback)(session_t *new_session)
Notify server of newly accepted session.
static void proxy_try_delete_session(session_t *s, u8 is_active_open)
Definition: proxy.c:158
struct _svm_fifo svm_fifo_t
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:106
static void active_open_cleanup_callback(session_t *s, session_cleanup_ntf_t ntf)
Definition: proxy.c:610
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static const u32 test_srv_crt_rsa_len
Definition: tls_test.h:47
#define u8
Padding.
Definition: clib.h:121
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
static void proxy_cleanup_callback(session_t *s, session_cleanup_ntf_t ntf)
Definition: proxy.c:428