FD.io VPP  v19.01.3-6-g70449b9b9
Vector Packet Processing
http_server.c
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2015-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 <vnet/vnet.h>
19 
20 typedef enum
21 {
24 
25 typedef struct
26 {
31 
32 typedef enum
33 {
38 typedef struct
39 {
40  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
41 #define _(type, name) type name;
43 #undef _
49 
50 typedef struct
51 {
55 
57 
59 
61 
62  /* Sever's event queue */
64 
65  /* API client handle */
67 
69 
70  /* process node index for evnt scheduling */
72 
76  u8 *uri;
80 
82 
83 static void
85 {
86  clib_rwlock_reader_lock (&http_server_main.sessions_lock);
87 }
88 
89 static void
91 {
92  clib_rwlock_reader_unlock (&http_server_main.sessions_lock);
93 }
94 
95 static void
97 {
98  clib_rwlock_writer_lock (&http_server_main.sessions_lock);
99 }
100 
101 static void
103 {
104  clib_rwlock_writer_unlock (&http_server_main.sessions_lock);
105 }
106 
107 static void
108 http_server_session_lookup_add (u32 thread_index, u32 s_index, u32 hs_index)
109 {
111  vec_validate (hsm->session_to_http_session[thread_index], s_index);
112  hsm->session_to_http_session[thread_index][s_index] = hs_index;
113 }
114 
115 static void
116 http_server_session_lookup_del (u32 thread_index, u32 s_index)
117 {
119  hsm->session_to_http_session[thread_index][s_index] = ~0;
120 }
121 
122 static http_session_t *
123 http_server_session_lookup (u32 thread_index, u32 s_index)
124 {
126  u32 hs_index;
127 
128  if (s_index < vec_len (hsm->session_to_http_session[thread_index]))
129  {
130  hs_index = hsm->session_to_http_session[thread_index][s_index];
131  if (hs_index < vec_len (hsm->sessions[thread_index]))
132  return &hsm->sessions[thread_index][hs_index];
133  }
134  return 0;
135 }
136 
137 static http_session_t *
139 {
141  http_session_t *hs;
142  pool_get (hsm->sessions[thread_index], hs);
143  memset (hs, 0, sizeof (*hs));
144  hs->session_index = hs - hsm->sessions[thread_index];
145  hs->thread_index = thread_index;
146  return hs;
147 }
148 
149 static http_session_t *
150 http_server_session_get (u32 thread_index, u32 hs_index)
151 {
153  return pool_elt_at_index (hsm->sessions[thread_index], hs_index);
154 }
155 
156 static void
158 {
160  pool_put (hsm->sessions[hs->thread_index], hs);
161  if (CLIB_DEBUG)
162  memset (hs, 0xfa, sizeof (*hs));
163 }
164 
165 static void
167 {
168  if (!hs)
169  return;
171  vec_free (hs->rx_buf);
173 }
174 
175 static void
177 {
181  vlib_node_t *n;
182  u32 node_index;
183  http_server_args **save_args;
184 
185  node_index = args->node_index;
186  ASSERT (node_index != 0);
187 
188  n = vlib_get_node (vm, node_index);
189  rt = vlib_node_get_runtime (vm, n->index);
190  save_args = vlib_node_get_runtime_data (vm, n->index);
191 
192  /* Reset process session pointer */
193  clib_mem_free (*save_args);
194  *save_args = 0;
195 
196  /* Turn off the process node */
197  vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);
198 
199  /* add node index to the freelist */
200  vec_add1 (hsm->free_http_cli_process_node_indices, node_index);
201 }
202 
203 /* *INDENT-OFF* */
204 static const char *http_ok =
205  "HTTP/1.1 200 OK\r\n";
206 
207 static const char *http_response =
208  "Content-Type: text/html\r\n"
209  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
210  "Connection: close \r\n"
211  "Pragma: no-cache\r\n"
212  "Content-Length: %d\r\n\r\n%s";
213 
214 static const char *http_error_template =
215  "HTTP/1.1 %s\r\n"
216  "Content-Type: text/html\r\n"
217  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
218  "Connection: close\r\n"
219  "Pragma: no-cache\r\n"
220  "Content-Length: 0\r\n\r\n";
221 
222 /* Header, including incantation to suppress favicon.ico requests */
223 static const char *html_header_template =
224  "<html><head><title>%v</title></head>"
225  "<link rel=\"icon\" href=\"data:,\">"
226  "<body><pre>";
227 
228 static const char *html_footer =
229  "</pre></body></html>\r\n";
230 
231 static const char *html_header_static =
232  "<html><head><title>static reply</title></head>"
233  "<link rel=\"icon\" href=\"data:,\">"
234  "<body><pre>hello</pre></body></html>\r\n";
235 /* *INDENT-ON* */
236 
237 static u8 *static_http;
238 static u8 *static_ok;
239 
240 static void
241 http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
242 {
243  u8 **output_vecp = (u8 **) arg;
244  u8 *output_vec;
245  u32 offset;
246 
247  output_vec = *output_vecp;
248 
249  offset = vec_len (output_vec);
250  vec_validate (output_vec, offset + buffer_bytes - 1);
251  clib_memcpy_fast (output_vec + offset, buffer, buffer_bytes);
252 
253  *output_vecp = output_vec;
254 }
255 
256 void
258 {
260  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
262  f64 last_sent_timer = vlib_time_now (vm);
263  u32 offset, bytes_to_send;
264  f64 delay = 10e-3;
265 
266  bytes_to_send = vec_len (data);
267  offset = 0;
268 
269  while (bytes_to_send > 0)
270  {
271  int actual_transfer;
272 
273  actual_transfer = svm_fifo_enqueue_nowait
274  (hs->tx_fifo, bytes_to_send, data + offset);
275 
276  /* Made any progress? */
277  if (actual_transfer <= 0)
278  {
279  vlib_process_suspend (vm, delay);
280  /* 10s deadman timer */
281  if (vlib_time_now (vm) > last_sent_timer + 10.0)
282  {
283  a->handle = hs->vpp_session_handle;
284  a->app_index = hsm->app_index;
286  break;
287  }
288  /* Exponential backoff, within reason */
289  if (delay < 1.0)
290  delay = delay * 2.0;
291  }
292  else
293  {
294  last_sent_timer = vlib_time_now (vm);
295  offset += actual_transfer;
296  bytes_to_send -= actual_transfer;
297 
298  if (svm_fifo_set_event (hs->tx_fifo))
299  session_send_io_evt_to_thread (hs->tx_fifo,
301  delay = 10e-3;
302  }
303  }
304 }
305 
306 static void
307 send_error (http_session_t * hs, char *str)
308 {
309  u8 *data;
310 
311  data = format (0, http_error_template, str);
312  send_data (hs, data);
313  vec_free (data);
314 }
315 
316 static uword
318  vlib_frame_t * f)
319 {
320  u8 *request = 0, *reply = 0, *http = 0, *html = 0;
322  http_server_args **save_args;
323  http_server_args *args;
324  unformat_input_t input;
325  http_session_t *hs;
326  int i;
327 
328  save_args = vlib_node_get_runtime_data (hsm->vlib_main, rt->node_index);
329  args = *save_args;
330 
332 
333  hs = http_server_session_get (args->thread_index, args->hs_index);
334  ASSERT (hs);
335 
336  request = hs->rx_buf;
337  if (vec_len (request) < 7)
338  {
339  send_error (hs, "400 Bad Request");
340  goto out;
341  }
342 
343  for (i = 0; i < vec_len (request) - 4; i++)
344  {
345  if (request[i] == 'G' &&
346  request[i + 1] == 'E' &&
347  request[i + 2] == 'T' && request[i + 3] == ' ')
348  goto found;
349  }
350 bad_request:
351  send_error (hs, "400 Bad Request");
352  goto out;
353 
354 found:
355  /* Lose "GET " */
356  vec_delete (request, i + 5, 0);
357 
358  /* Replace slashes with spaces, stop at the end of the path */
359  i = 0;
360  while (1)
361  {
362  if (request[i] == '/')
363  request[i] = ' ';
364  else if (request[i] == ' ')
365  {
366  /* vlib_cli_input is vector-based, no need for a NULL */
367  _vec_len (request) = i;
368  break;
369  }
370  i++;
371  /* Should never happen */
372  if (i == vec_len (request))
373  goto bad_request;
374  }
375 
376  /* Generate the html header */
377  html = format (0, html_header_template, request /* title */ );
378 
379  /* Run the command */
380  unformat_init_vector (&input, vec_dup (request));
381  vlib_cli_input (vm, &input, http_cli_output, (uword) & reply);
382  unformat_free (&input);
383  request = 0;
384 
385  /* Generate the html page */
386  html = format (html, "%v", reply);
387  html = format (html, html_footer);
388  /* And the http reply */
389  http = format (0, http_ok, vec_len (http_ok));
390  http = format (http, http_response, vec_len (html), html);
391 
392  /* Send it */
393  send_data (hs, http);
394 
395 out:
396  /* Cleanup */
398  vec_free (reply);
399  vec_free (html);
400  vec_free (http);
401 
402  http_process_free (args);
403  return (0);
404 }
405 
406 static void
408 {
409  char *name;
410  vlib_node_t *n;
412  vlib_main_t *vm = hsm->vlib_main;
414  http_server_args **save_args;
415 
417  {
419  vlib_node_set_state (vm, n->index, VLIB_NODE_STATE_POLLING);
420  _vec_len (hsm->free_http_cli_process_node_indices) = l - 1;
421  }
422  else
423  {
424  static vlib_node_registration_t r = {
425  .function = http_cli_process,
426  .type = VLIB_NODE_TYPE_PROCESS,
427  .process_log2_n_stack_bytes = 16,
428  .runtime_data_bytes = sizeof (void *),
429  };
430 
431  name = (char *) format (0, "http-cli-%d", l);
432  r.name = name;
433  vlib_register_node (vm, &r);
434  vec_free (name);
435 
436  n = vlib_get_node (vm, r.index);
437  }
438 
439  /* Save the node index in the args. It won't be zero. */
440  args->node_index = n->index;
441 
442  /* Save the args (pointer) in the node runtime */
443  save_args = vlib_node_get_runtime_data (vm, n->index);
444  *save_args = args;
445 
447 }
448 
449 static void
451 {
452  alloc_http_process ((http_server_args *) cb_args);
453 }
454 
455 static int
457 {
458  u32 max_dequeue, cursize;
459  int n_read;
460 
461  cursize = vec_len (hs->rx_buf);
462  max_dequeue = svm_fifo_max_dequeue (hs->rx_fifo);
463  if (PREDICT_FALSE (max_dequeue == 0))
464  return -1;
465 
466  vec_validate (hs->rx_buf, cursize + max_dequeue - 1);
467  n_read = app_recv_stream_raw (hs->rx_fifo, hs->rx_buf + cursize,
468  max_dequeue, 0, 0 /* peek */ );
469  ASSERT (n_read == max_dequeue);
470  if (svm_fifo_is_empty (hs->rx_fifo))
471  svm_fifo_unset_event (hs->rx_fifo);
472 
473  _vec_len (hs->rx_buf) = cursize + n_read;
474  return 0;
475 }
476 
477 static int
479 {
480  http_server_args *args;
481  http_session_t *hs;
482  int rv;
483 
485 
486  hs = http_server_session_lookup (s->thread_index, s->session_index);
487  if (!hs || hs->session_state != HTTP_STATE_ESTABLISHED)
488  return -1;
489 
490  rv = session_rx_request (hs);
491  if (rv)
492  return rv;
493 
494  /* send the command to a new/recycled vlib process */
495  args = clib_mem_alloc (sizeof (*args));
496  args->hs_index = hs->session_index;
497  args->thread_index = hs->thread_index;
498 
500 
501  /* Send an RPC request via the thread-0 input node */
502  if (vlib_get_thread_index () != 0)
504  else
505  alloc_http_process (args);
506  return 0;
507 }
508 
509 static int
511 {
513  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
514  http_session_t *hs;
515  u32 request_len;
516  u8 *request = 0;
517  int i, rv;
518 
519  hs = http_server_session_lookup (s->thread_index, s->session_index);
520  if (!hs || hs->session_state == HTTP_STATE_CLOSED)
521  return 0;
522 
523  /* ok 200 was sent */
524  if (hs->session_state == HTTP_STATE_OK_SENT)
525  goto send_data;
526 
527  rv = session_rx_request (hs);
528  if (rv)
529  goto wait_for_data;
530 
531  request = hs->rx_buf;
532  request_len = vec_len (request);
533  if (vec_len (request) < 7)
534  {
535  send_error (hs, "400 Bad Request");
536  goto close_session;
537  }
538 
539  for (i = 0; i < request_len - 4; i++)
540  {
541  if (request[i] == 'G' &&
542  request[i + 1] == 'E' &&
543  request[i + 2] == 'T' && request[i + 3] == ' ')
544  goto find_end;
545  }
546  send_error (hs, "400 Bad Request");
547  goto close_session;
548 
549 find_end:
550 
551  /* check for the end sequence: /r/n/r/n */
552  if (request[request_len - 1] != 0xa || request[request_len - 3] != 0xa
553  || request[request_len - 2] != 0xd || request[request_len - 4] != 0xd)
554  goto wait_for_data;
555 
556  /* send 200 OK first */
557  send_data (hs, static_ok);
558  hs->session_state = HTTP_STATE_OK_SENT;
559  goto postpone;
560 
561 send_data:
562  send_data (hs, static_http);
564 
565 close_session:
566  a->handle = session_handle (s);
567  a->app_index = hsm->app_index;
569  return 0;
570 
571 postpone:
572  svm_fifo_set_event (hs->rx_fifo);
574  return 0;
575 
576 wait_for_data:
577  return 0;
578 }
579 
580 static int
582 {
584  http_session_t *hs;
585 
586  hsm->vpp_queue[s->thread_index] =
587  session_manager_get_vpp_event_queue (s->thread_index);
588 
589  if (!hsm->is_static)
591 
592  hs = http_server_session_alloc (s->thread_index);
593  http_server_session_lookup_add (s->thread_index, s->session_index,
594  hs->session_index);
595  hs->rx_fifo = s->server_rx_fifo;
596  hs->tx_fifo = s->server_tx_fifo;
597  hs->vpp_session_index = s->session_index;
599  hs->session_state = HTTP_STATE_ESTABLISHED;
600 
601  if (!hsm->is_static)
603 
604  s->session_state = SESSION_STATE_READY;
605  return 0;
606 }
607 
608 static void
610 {
612  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
613  http_session_t *hs;
614 
615  if (!hsm->is_static)
617 
618  hs = http_server_session_lookup (s->thread_index, s->session_index);
620 
621  if (!hsm->is_static)
623 
624  a->handle = session_handle (s);
625  a->app_index = hsm->app_index;
627 }
628 
629 static void
631 {
633  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
634  http_session_t *hs;
635 
636  if (!hsm->is_static)
638 
639  hs = http_server_session_lookup (s->thread_index, s->session_index);
641 
642  if (!hsm->is_static)
644 
645  a->handle = session_handle (s);
646  a->app_index = hsm->app_index;
648 }
649 
650 static int
652  stream_session_t * s, u8 is_fail)
653 {
654  clib_warning ("called...");
655  return -1;
656 }
657 
658 static int
659 http_server_add_segment_callback (u32 client_index, u64 segment_handle)
660 {
661  clib_warning ("called...");
662  return -1;
663 }
664 
666  .session_accept_callback = http_server_session_accept_callback,
667  .session_disconnect_callback = http_server_session_disconnect_callback,
668  .session_connected_callback = http_server_session_connected_callback,
669  .add_segment_callback = http_server_add_segment_callback,
670  .builtin_app_rx_callback = http_server_rx_callback,
671  .session_reset_callback = http_server_session_reset_callback
672 };
673 
674 static int
676 {
677  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
678  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
680  u64 options[APP_OPTIONS_N_OPTIONS];
681  vnet_app_attach_args_t _a, *a = &_a;
682  u32 segment_size = 128 << 20;
683 
684  clib_memset (a, 0, sizeof (*a));
685  clib_memset (options, 0, sizeof (options));
686 
687  if (hsm->private_segment_size)
688  segment_size = hsm->private_segment_size;
689 
690  a->api_client_index = ~0;
691  a->name = format (0, "test_http_server");
692  a->session_cb_vft = &http_server_session_cb_vft;
693  a->options = options;
694  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
695  a->options[APP_OPTIONS_RX_FIFO_SIZE] =
696  hsm->fifo_size ? hsm->fifo_size : 8 << 10;
697  a->options[APP_OPTIONS_TX_FIFO_SIZE] =
698  hsm->fifo_size ? hsm->fifo_size : 32 << 10;
699  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
701 
702  if (vnet_application_attach (a))
703  {
704  vec_free (a->name);
705  clib_warning ("failed to attach server");
706  return -1;
707  }
708  vec_free (a->name);
709  hsm->app_index = a->app_index;
710 
711  clib_memset (a_cert, 0, sizeof (*a_cert));
712  a_cert->app_index = a->app_index;
713  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
715  vnet_app_add_tls_cert (a_cert);
716 
717  clib_memset (a_key, 0, sizeof (*a_key));
718  a_key->app_index = a->app_index;
719  vec_validate (a_key->key, test_srv_key_rsa_len);
721  vnet_app_add_tls_key (a_key);
722 
723  return 0;
724 }
725 
726 static int
728 {
730  vnet_bind_args_t _a, *a = &_a;
731  clib_memset (a, 0, sizeof (*a));
732  a->app_index = hsm->app_index;
733  a->uri = "tcp://0.0.0.0/80";
734  if (hsm->uri)
735  a->uri = (char *) hsm->uri;
736  return vnet_bind_uri (a);
737 }
738 
739 static int
741 {
744  u32 num_threads;
745 
746  num_threads = 1 /* main thread */ + vtm->n_threads;
747  vec_validate (hsm->vpp_queue, num_threads - 1);
748  vec_validate (hsm->sessions, num_threads - 1);
749  vec_validate (hsm->session_to_http_session, num_threads - 1);
750 
752 
753  if (http_server_attach ())
754  {
755  clib_warning ("failed to attach server");
756  return -1;
757  }
758  if (http_server_listen ())
759  {
760  clib_warning ("failed to start listening");
761  return -1;
762  }
763  return 0;
764 }
765 
766 static clib_error_t *
768  unformat_input_t * input,
769  vlib_cli_command_t * cmd)
770 {
772  u64 seg_size;
773  u8 *html;
774  int rv;
775 
776  hsm->prealloc_fifos = 0;
777  hsm->private_segment_size = 0;
778  hsm->fifo_size = 0;
779  hsm->is_static = 0;
781  {
782  if (unformat (input, "static"))
783  hsm->is_static = 1;
784  else if (unformat (input, "prealloc-fifos %d", &hsm->prealloc_fifos))
785  ;
786  else if (unformat (input, "private-segment-size %U",
787  unformat_memory_size, &seg_size))
788  {
789  if (seg_size >= 0x100000000ULL)
790  {
791  vlib_cli_output (vm, "private segment size %llu, too large",
792  seg_size);
793  return 0;
794  }
795  hsm->private_segment_size = seg_size;
796  }
797  else if (unformat (input, "fifo-size %d", &hsm->fifo_size))
798  hsm->fifo_size <<= 10;
799  else if (unformat (input, "uri %s", &hsm->uri))
800  ;
801  else
802  return clib_error_return (0, "unknown input `%U'",
803  format_unformat_error, input);
804  }
805  if (hsm->my_client_index != (u32) ~ 0)
806  return clib_error_return (0, "test http server is already running");
807 
808  vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
809 
810  if (hsm->is_static)
811  {
812  http_server_session_cb_vft.builtin_app_rx_callback =
814  html = format (0, html_header_static);
815  static_http = format (0, http_response, vec_len (html), html);
816  static_ok = format (0, http_ok);
817  }
818  rv = http_server_create (vm);
819  switch (rv)
820  {
821  case 0:
822  break;
823  default:
824  return clib_error_return (0, "server_create returned %d", rv);
825  }
826  return 0;
827 }
828 
829 /* *INDENT-OFF* */
830 VLIB_CLI_COMMAND (http_server_create_command, static) =
831 {
832  .path = "test http server",
833  .short_help = "test http server",
834  .function = http_server_create_command_fn,
835 };
836 /* *INDENT-ON* */
837 
838 static clib_error_t *
840 {
842 
843  hsm->my_client_index = ~0;
844  hsm->vlib_main = vm;
845  return 0;
846 }
847 
849 
850 /*
851 * fd.io coding-style-patch-verification: ON
852 *
853 * Local Variables:
854 * eval: (c-set-style "gnu")
855 * End:
856 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
#define foreach_app_session_field
flag for dgram mode
static void clib_rwlock_reader_lock(clib_rwlock_t *p)
Definition: lock.h:139
static void http_server_sessions_reader_unlock(void)
Definition: http_server.c:90
static int app_recv_stream_raw(svm_fifo_t *f, u8 *buf, u32 len, u8 clear_evt, u8 peek)
static void http_server_session_disconnect_callback(stream_session_t *s)
Definition: http_server.c:609
vlib_main_t vlib_global_main
Definition: main.c:1850
#define CLIB_CACHE_LINE_ALIGN_MARK(mark)
Definition: cache.h:60
static int http_server_create(vlib_main_t *vm)
Definition: http_server.c:740
a
Definition: bitmap.h:538
static void clib_rwlock_writer_lock(clib_rwlock_t *p)
Definition: lock.h:177
const u32 test_srv_crt_rsa_len
static const char * html_header_template
Definition: http_server.c:223
void vlib_cli_input(vlib_main_t *vm, unformat_input_t *input, vlib_cli_output_function_t *function, uword function_arg)
Definition: cli.c:725
svm_queue_t * vl_input_queue
Definition: http_server.c:63
static const char * http_response
Definition: http_server.c:207
int vnet_bind_uri(vnet_bind_args_t *a)
const u32 test_srv_key_rsa_len
unsigned long u64
Definition: types.h:89
static int session_rx_request(http_session_t *hs)
Definition: http_server.c:456
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
static void http_server_sessions_writer_unlock(void)
Definition: http_server.c:102
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:304
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:232
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:525
u32 vpp_session_index
Definition: http_server.c:46
void session_send_rpc_evt_to_thread(u32 thread_index, void *fp, void *rpc_args)
Definition: session.c:111
int i
static void http_process_free(http_server_args *args)
Definition: http_server.c:176
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static int http_server_session_accept_callback(stream_session_t *s)
Definition: http_server.c:581
struct _vnet_application_add_tls_cert_args_t vnet_app_add_tls_cert_args_t
static void http_server_session_lookup_add(u32 thread_index, u32 s_index, u32 hs_index)
Definition: http_server.c:108
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
Definition: application.c:1976
unsigned char u8
Definition: types.h:56
static void alloc_http_process_callback(void *cb_args)
Definition: http_server.c:450
double f64
Definition: types.h:142
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
Definition: node_funcs.h:422
static int svm_fifo_is_empty(svm_fifo_t *f)
Definition: svm_fifo.h:136
static svm_msg_q_t * session_manager_get_vpp_event_queue(u32 thread_index)
Definition: session.h:656
http_session_state_t
Definition: http_server.c:32
static int http_server_rx_callback_static(stream_session_t *s)
Definition: http_server.c:510
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
struct _vnet_disconnect_args_t vnet_disconnect_args_t
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Definition: svm_fifo.h:124
struct _stream_session_cb_vft session_cb_vft_t
foreach_app_session_field u32 thread_index
Definition: http_server.c:44
static int http_server_listen()
Definition: http_server.c:727
#define clib_error_return(e, args...)
Definition: error.h:99
int svm_fifo_enqueue_nowait(svm_fifo_t *f, u32 max_bytes, const u8 *copy_from_here)
Definition: svm_fifo.c:530
svm_msg_q_t ** vpp_queue
Definition: http_server.c:56
unsigned int u32
Definition: types.h:88
struct _stream_session_t stream_session_t
int session_send_io_evt_to_thread(svm_fifo_t *f, session_evt_type_t evt_type)
Definition: session.c:88
static void http_server_sessions_writer_lock(void)
Definition: http_server.c:96
struct _vnet_app_attach_args_t vnet_app_attach_args_t
static void http_server_session_free(http_session_t *hs)
Definition: http_server.c:157
static session_cb_vft_t http_server_session_cb_vft
Definition: http_server.c:665
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
Definition: application.c:1988
static void http_server_session_reset_callback(stream_session_t *s)
Definition: http_server.c:630
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:511
static void clib_rwlock_init(clib_rwlock_t *p)
Definition: lock.h:122
static u8 * static_ok
Definition: http_server.c:238
static void clib_rwlock_reader_unlock(clib_rwlock_t *p)
Definition: lock.h:157
u64 vpp_session_handle
Definition: http_server.c:47
static const char * html_header_static
Definition: http_server.c:231
static u8 * static_http
Definition: http_server.c:237
struct _unformat_input_t unformat_input_t
static session_handle_t session_handle(stream_session_t *s)
Definition: session.h:364
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:375
static void * vlib_node_get_runtime_data(vlib_main_t *vm, u32 node_index)
Get node runtime private data by node index.
Definition: node_funcs.h:110
#define PREDICT_FALSE(x)
Definition: clib.h:111
static void svm_fifo_unset_event(svm_fifo_t *f)
Unsets fifo event flag.
Definition: svm_fifo.h:180
static const char * html_footer
Definition: http_server.c:228
u32 node_index
Node index.
Definition: node.h:518
const char test_srv_crt_rsa[]
u8 name[64]
Definition: memclnt.api:152
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1529
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1031
static u8 svm_fifo_set_event(svm_fifo_t *f)
Sets fifo event flag.
Definition: svm_fifo.h:167
static void clib_rwlock_writer_unlock(clib_rwlock_t *p)
Definition: lock.h:185
vlib_main_t * vlib_main
Definition: http_server.c:78
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
u32 runtime_index
Definition: node.h:307
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:212
static int http_server_attach()
Definition: http_server.c:675
vlib_main_t * vm
Definition: buffer.c:301
static int http_server_session_connected_callback(u32 app_index, u32 api_context, stream_session_t *s, u8 is_fail)
Definition: http_server.c:651
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
#define clib_warning(format, args...)
Definition: error.h:59
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:89
int vnet_disconnect_session(vnet_disconnect_args_t *a)
u32 ** session_to_http_session
Definition: http_server.c:54
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
#define ASSERT(truth)
static http_session_t * http_server_session_get(u32 thread_index, u32 hs_index)
Definition: http_server.c:150
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:788
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:520
static void clib_mem_free(void *p)
Definition: mem.h:205
struct _vnet_application_add_tls_key_args_t vnet_app_add_tls_key_args_t
static void http_server_session_lookup_del(u32 thread_index, u32 s_index)
Definition: http_server.c:116
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:148
static void * clib_mem_alloc(uword size)
Definition: mem.h:132
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
uword * handler_by_get_request
Definition: http_server.c:58
static http_session_t * http_server_session_alloc(u32 thread_index)
Definition: http_server.c:138
struct _vlib_node_registration vlib_node_registration_t
static clib_error_t * http_server_main_init(vlib_main_t *vm)
Definition: http_server.c:839
http_server_main_t http_server_main
Definition: http_server.c:81
static void alloc_http_process(http_server_args *args)
Definition: http_server.c:407
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_error_t * vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
static int http_server_add_segment_callback(u32 client_index, u64 segment_handle)
Definition: http_server.c:659
vhost_user_req_t request
Definition: vhost_user.h:114
static clib_error_t * http_server_create_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: http_server.c:767
struct _svm_queue svm_queue_t
static const char * http_error_template
Definition: http_server.c:214
static int http_server_rx_callback(stream_session_t *s)
Definition: http_server.c:478
unformat_function_t unformat_memory_size
Definition: format.h:295
struct clib_bihash_value offset
template key/value backing page structure
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:32
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
static void http_server_session_cleanup(http_session_t *hs)
Definition: http_server.c:166
static const char * http_ok
Definition: http_server.c:204
http_session_t ** sessions
Definition: http_server.c:52
http_process_event_t
Definition: http_server.c:20
void vlib_start_process(vlib_main_t *vm, uword process_index)
Definition: main.c:1549
static http_session_t * http_server_session_lookup(u32 thread_index, u32 s_index)
Definition: http_server.c:123
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:762
struct _vnet_bind_args_t vnet_bind_args_t
static void http_cli_output(uword arg, u8 *buffer, uword buffer_bytes)
Definition: http_server.c:241
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
void send_data(http_session_t *hs, u8 *data)
Definition: http_server.c:257
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
const char test_srv_key_rsa[]
u32 * free_http_cli_process_node_indices
Definition: http_server.c:60
static uword http_cli_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: http_server.c:317
static void http_server_sessions_reader_lock(void)
Definition: http_server.c:84
static void send_error(http_session_t *hs, char *str)
Definition: http_server.c:307
clib_rwlock_t sessions_lock
Definition: http_server.c:53