FD.io VPP  v19.08-27-gf4dcae4
Vector Packet Processing
socket.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #define _GNU_SOURCE
19 #include <sys/socket.h>
20 #include <sys/types.h>
21 #include <sys/un.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <net/if.h>
26 #include <sys/ioctl.h>
27 #include <sys/uio.h>
28 #include <sys/mman.h>
29 #include <sys/prctl.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 
33 #include <socket.h>
34 #include <memif.h>
35 #include <memif_private.h>
36 
37 /* sends msg to socket */
38 static_fn int
39 memif_msg_send (int fd, memif_msg_t * msg, int afd)
40 {
41  struct msghdr mh = { 0 };
42  struct iovec iov[1];
43  char ctl[CMSG_SPACE (sizeof (int))];
44  int rv, err = MEMIF_ERR_SUCCESS; /* 0 */
45 
46  iov[0].iov_base = (void *) msg;
47  iov[0].iov_len = sizeof (memif_msg_t);
48  mh.msg_iov = iov;
49  mh.msg_iovlen = 1;
50 
51  if (afd > 0)
52  {
53  struct cmsghdr *cmsg;
54  memset (&ctl, 0, sizeof (ctl));
55  mh.msg_control = ctl;
56  mh.msg_controllen = sizeof (ctl);
57  cmsg = CMSG_FIRSTHDR (&mh);
58  cmsg->cmsg_len = CMSG_LEN (sizeof (int));
59  cmsg->cmsg_level = SOL_SOCKET;
60  cmsg->cmsg_type = SCM_RIGHTS;
61  memcpy (CMSG_DATA (cmsg), &afd, sizeof (int));
62  }
63  rv = sendmsg (fd, &mh, 0);
64  if (rv < 0)
65  err = memif_syscall_error_handler (errno);
66  DBG ("Message type %u sent", msg->type);
67  return err;
68 }
69 
70 /* response from memif master - master is ready to handle next message */
71 static_fn int
73 {
77  if (e == NULL)
78  return memif_syscall_error_handler (errno);
79 
80  memset (&e->msg, 0, sizeof (e->msg));
82  e->fd = -1;
83 
84  e->next = NULL;
85  if (c->msg_queue == NULL)
86  {
87  c->msg_queue = e;
88  return MEMIF_ERR_SUCCESS; /* 0 */
89  }
90 
91  memif_msg_queue_elt_t *cur = c->msg_queue;
92  while (cur->next != NULL)
93  {
94  cur = cur->next;
95  }
96  cur->next = e;
97 
98  return MEMIF_ERR_SUCCESS; /* 0 */
99 }
100 
101 static_fn int
103 {
105  memif_msg_t msg = { 0 };
106  memif_msg_hello_t *h = &msg.hello;
114 
115  strncpy ((char *) h->name, (char *) lm->app_name,
116  strlen ((char *) lm->app_name));
117 
118  /* msg hello is not enqueued but sent directly,
119  because it is the first msg to be sent */
120  return memif_msg_send (fd, &msg, -1);
121 }
122 
123 /* send id and secret (optional) for interface identification */
124 static_fn int
126 {
130  if (e == NULL)
131  return memif_syscall_error_handler (errno);
132  memset (e, 0, sizeof (memif_msg_queue_elt_t));
133 
134  memset (&e->msg, 0, sizeof (e->msg));
135  memif_msg_init_t *i = &e->msg.init;
136 
138  e->fd = -1;
139  i->version = MEMIF_VERSION;
140  i->id = c->args.interface_id;
141  i->mode = c->args.mode;
142 
143  strncpy ((char *) i->name, (char *) lm->app_name,
144  strlen ((char *) lm->app_name));
145  if (strlen ((char *) c->args.secret) > 0)
146  strncpy ((char *) i->secret, (char *) c->args.secret, sizeof (i->secret));
147 
148  e->next = NULL;
149  if (c->msg_queue == NULL)
150  {
151  c->msg_queue = e;
152  return MEMIF_ERR_SUCCESS; /* 0 */
153  }
154 
155  memif_msg_queue_elt_t *cur = c->msg_queue;
156  while (cur->next != NULL)
157  {
158  cur = cur->next;
159  }
160  cur->next = e;
161 
162  return MEMIF_ERR_SUCCESS; /* 0 */
163 }
164 
165 /* send information about region specified by region_index */
166 static_fn int
168 {
170  memif_region_t *mr = &c->regions[region_index];
171 
174  if (e == NULL)
175  return memif_syscall_error_handler (errno);
176 
177  memset (&e->msg, 0, sizeof (e->msg));
179 
181  e->fd = mr->fd;
182  ar->index = region_index;
183  ar->size = mr->region_size;
184 
185  e->next = NULL;
186  if (c->msg_queue == NULL)
187  {
188  c->msg_queue = e;
189  return MEMIF_ERR_SUCCESS; /* 0 */
190  }
191 
192  memif_msg_queue_elt_t *cur = c->msg_queue;
193  while (cur->next != NULL)
194  {
195  cur = cur->next;
196  }
197  cur->next = e;
198 
199  return MEMIF_ERR_SUCCESS; /* 0 */
200 }
201 
202 /* send information about ring specified by direction (S2M | M2S) and index */
203 static_fn int
204 memif_msg_enq_add_ring (memif_connection_t * c, uint8_t index, uint8_t dir)
205 {
209  if (e == NULL)
210  return memif_syscall_error_handler (errno);
211 
212  memset (&e->msg, 0, sizeof (e->msg));
214 
216 
217  /* TODO: support multiple rings */
218  memif_queue_t *mq;
219  if (dir == MEMIF_RING_M2S)
220  mq = &c->rx_queues[index];
221  else
222  mq = &c->tx_queues[index];
223 
224  e->fd = mq->int_fd;
225  ar->index = index;
226  ar->offset = mq->offset;
227  ar->region = mq->region;
228  ar->log2_ring_size = mq->log2_ring_size;
229  ar->flags = (dir == MEMIF_RING_S2M) ? MEMIF_MSG_ADD_RING_FLAG_S2M : 0;
230  ar->private_hdr_size = 0;
231 
232  e->next = NULL;
233  if (c->msg_queue == NULL)
234  {
235  c->msg_queue = e;
236  return MEMIF_ERR_SUCCESS; /* 0 */
237  }
238 
239  memif_msg_queue_elt_t *cur = c->msg_queue;
240  while (cur->next != NULL)
241  {
242  cur = cur->next;
243  }
244  cur->next = e;
245 
246  return MEMIF_ERR_SUCCESS; /* 0 */
247 }
248 
249 /* used as connection request from slave */
250 static_fn int
252 {
256  if (e == NULL)
257  return memif_syscall_error_handler (errno);
258 
259  memset (&e->msg, 0, sizeof (e->msg));
261 
263  e->fd = -1;
264  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
265  strlen ((char *) c->args.interface_name));
266 
267  e->next = NULL;
268  if (c->msg_queue == NULL)
269  {
270  c->msg_queue = e;
271  return MEMIF_ERR_SUCCESS; /* 0 */
272  }
273 
274  memif_msg_queue_elt_t *cur = c->msg_queue;
275  while (cur->next != NULL)
276  {
277  cur = cur->next;
278  }
279  cur->next = e;
280 
281  return MEMIF_ERR_SUCCESS; /* 0 */
282 }
283 
284 /* used as confirmation of connection by master */
285 static_fn int
287 {
291  if (e == NULL)
292  return memif_syscall_error_handler (errno);
293 
294  memset (&e->msg, 0, sizeof (e->msg));
296 
298  e->fd = -1;
299  strncpy ((char *) cm->if_name, (char *) c->args.interface_name,
300  strlen ((char *) c->args.interface_name));
301 
302  e->next = NULL;
303  if (c->msg_queue == NULL)
304  {
305  c->msg_queue = e;
306  return MEMIF_ERR_SUCCESS; /* 0 */
307  }
308 
309  memif_msg_queue_elt_t *cur = c->msg_queue;
310  while (cur->next != NULL)
311  {
312  cur = cur->next;
313  }
314  cur->next = e;
315 
316  return MEMIF_ERR_SUCCESS; /* 0 */
317 }
318 
319 /* immediately send disconnect msg */
320  /* specifie protocol for disconnect msg err_code
321  so that it will be compatible with VPP? (header/doc) */
322 int
323 memif_msg_send_disconnect (int fd, uint8_t * err_string, uint32_t err_code)
324 {
325  memif_msg_t msg = { 0 };
327 
329  d->code = err_code;
330  uint16_t l = strlen ((char *) err_string);
331  if (l > 96)
332  {
333  DBG ("Disconnect string too long. Sending first 96 characters.");
334  l = 96;
335  }
336  strncpy ((char *) d->string, (char *) err_string, l);
337 
338  return memif_msg_send (fd, &msg, -1);
339 }
340 
341 static_fn int
343 {
344  memif_msg_hello_t *h = &msg->hello;
345 
346  if (msg->hello.min_version > MEMIF_VERSION ||
348  {
349  DBG ("incompatible protocol version");
350  return MEMIF_ERR_PROTO;
351  }
352 
353  c->run_args.num_s2m_rings = memif_min (h->max_s2m_ring + 1,
354  c->args.num_s2m_rings);
355  c->run_args.num_m2s_rings = memif_min (h->max_m2s_ring + 1,
356  c->args.num_m2s_rings);
357  c->run_args.log2_ring_size = memif_min (h->max_log2_ring_size,
358  c->args.log2_ring_size);
359  c->run_args.buffer_size = c->args.buffer_size;
360  strncpy ((char *) c->remote_name, (char *) h->name,
361  strlen ((char *) h->name));
362 
363  return MEMIF_ERR_SUCCESS; /* 0 */
364 }
365 
366 /* handle interface identification (id, secret (optional)) */
367 static_fn int
369 {
370  memif_msg_init_t *i = &msg->init;
371  memif_list_elt_t *elt = NULL;
372  memif_list_elt_t elt2;
375  uint8_t err_string[96];
376  memset (err_string, 0, sizeof (char) * 96);
377  int err = MEMIF_ERR_SUCCESS; /* 0 */
378  if (i->version != MEMIF_VERSION)
379  {
380  DBG ("MEMIF_VER_ERR");
381  strncpy ((char *) err_string, MEMIF_VER_ERR, strlen (MEMIF_VER_ERR));
382  err = MEMIF_ERR_PROTO;
383  goto error;
384  }
385 
386  get_list_elt (&elt, ms->interface_list, ms->interface_list_len, i->id);
387  if (elt == NULL)
388  {
389  DBG ("MEMIF_ID_ERR");
390  strncpy ((char *) err_string, MEMIF_ID_ERR, strlen (MEMIF_ID_ERR));
391  err = MEMIF_ERR_ID;
392  goto error;
393  }
394 
395  c = (memif_connection_t *) elt->data_struct;
396 
397  if (!(c->args.is_master))
398  {
399  DBG ("MEMIF_SLAVE_ERR");
400  strncpy ((char *) err_string, MEMIF_SLAVE_ERR,
401  strlen (MEMIF_SLAVE_ERR));
402  err = MEMIF_ERR_ACCSLAVE;
403  goto error;
404  }
405  if (c->fd != -1)
406  {
407  DBG ("MEMIF_CONN_ERR");
408  strncpy ((char *) err_string, MEMIF_CONN_ERR, strlen (MEMIF_CONN_ERR));
409  err = MEMIF_ERR_ALRCONN;
410  goto error;
411  }
412 
413  c->fd = fd;
414 
415  if (i->mode != c->args.mode)
416  {
417  DBG ("MEMIF_MODE_ERR");
418  strncpy ((char *) err_string, MEMIF_MODE_ERR, strlen (MEMIF_MODE_ERR));
419  err = MEMIF_ERR_MODE;
420  goto error;
421  }
422 
423  strncpy ((char *) c->remote_name, (char *) i->name,
424  strlen ((char *) i->name));
425 
426  if (strlen ((char *) c->args.secret) > 0)
427  {
428  int r;
429  if (strlen ((char *) i->secret) > 0)
430  {
431  if (strlen ((char *) c->args.secret) != strlen ((char *) i->secret))
432  {
433  DBG ("MEMIF_SECRET_ERR");
434  strncpy ((char *) err_string,
436  err = MEMIF_ERR_SECRET;
437  goto error;
438  }
439  r = strncmp ((char *) i->secret, (char *) c->args.secret,
440  strlen ((char *) c->args.secret));
441  if (r != 0)
442  {
443  DBG ("MEMIF_SECRET_ERR");
444  strncpy ((char *) err_string,
446  err = MEMIF_ERR_SECRET;
447  goto error;
448  }
449  }
450  else
451  {
452  DBG ("MEMIF_NOSECRET_ERR");
453  strncpy ((char *) err_string,
455  err = MEMIF_ERR_NOSECRET;
456  goto error;
457  }
458  }
459 
460  c->read_fn = memif_conn_fd_read_ready;
461  c->write_fn = memif_conn_fd_write_ready;
462  c->error_fn = memif_conn_fd_error;
463 
464  elt2.key = c->fd;
465  elt2.data_struct = c;
466 
467  add_list_elt (&elt2, &lm->control_list, &lm->control_list_len);
469 
470  return err;
471 
472 error:
473  memif_msg_send_disconnect (fd, err_string, 0);
474  lm->control_fd_update (fd, MEMIF_FD_EVENT_DEL, c->private_ctx);
476  close (fd);
477  fd = -1;
478  return err;
479 }
480 
481 /* receive region information and add new region to connection (if possible) */
482 static_fn int
484  int fd)
485 {
487 
489  memif_region_t *mr;
490  if (fd < 0)
491  return MEMIF_ERR_NO_SHMFD;
492 
493  if (ar->index > MEMIF_MAX_REGION)
494  return MEMIF_ERR_MAXREG;
495 
496  mr =
497  (memif_region_t *) lm->realloc (c->regions,
498  sizeof (memif_region_t) *
499  (++c->regions_num));
500  if (mr == NULL)
501  return memif_syscall_error_handler (errno);
502  memset (mr + ar->index, 0, sizeof (memif_region_t));
503  c->regions = mr;
504  c->regions[ar->index].fd = fd;
505  c->regions[ar->index].region_size = ar->size;
506  c->regions[ar->index].addr = NULL;
507 
508  /* region 0 is never external */
509  if (lm->get_external_region_addr && (ar->index != 0))
510  c->regions[ar->index].is_external = 1;
511 
512  return MEMIF_ERR_SUCCESS; /* 0 */
513 }
514 
515 /* receive ring information and add new ring to connection queue
516  (based on direction S2M | M2S) */
517 static_fn int
519 {
521 
522  memif_msg_add_ring_t *ar = &msg->add_ring;
523 
524  memif_queue_t *mq;
525 
526  if (fd < 0)
527  return MEMIF_ERR_NO_INTFD;
528 
529  if (ar->private_hdr_size != 0)
530  return MEMIF_ERR_PRIVHDR;
531 
533  {
534  if (ar->index > MEMIF_MAX_S2M_RING)
535  return MEMIF_ERR_MAXRING;
536  if (ar->index >= c->args.num_s2m_rings)
537  return MEMIF_ERR_MAXRING;
538 
539  mq =
540  (memif_queue_t *) lm->realloc (c->rx_queues,
541  sizeof (memif_queue_t) *
542  (++c->rx_queues_num));
543  memset (mq + ar->index, 0, sizeof (memif_queue_t));
544  if (mq == NULL)
545  return memif_syscall_error_handler (errno);
546  c->rx_queues = mq;
547  c->rx_queues[ar->index].int_fd = fd;
548  c->rx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
549  c->rx_queues[ar->index].region = ar->region;
550  c->rx_queues[ar->index].offset = ar->offset;
551  c->run_args.num_s2m_rings++;
552  }
553  else
554  {
555  if (ar->index > MEMIF_MAX_M2S_RING)
556  return MEMIF_ERR_MAXRING;
557  if (ar->index >= c->args.num_m2s_rings)
558  return MEMIF_ERR_MAXRING;
559 
560  mq =
561  (memif_queue_t *) lm->realloc (c->tx_queues,
562  sizeof (memif_queue_t) *
563  (++c->tx_queues_num));
564  memset (mq + ar->index, 0, sizeof (memif_queue_t));
565  if (mq == NULL)
566  return memif_syscall_error_handler (errno);
567  c->tx_queues = mq;
568  c->tx_queues[ar->index].int_fd = fd;
569  c->tx_queues[ar->index].log2_ring_size = ar->log2_ring_size;
570  c->tx_queues[ar->index].region = ar->region;
571  c->tx_queues[ar->index].offset = ar->offset;
572  c->run_args.num_m2s_rings++;
573  }
574 
575  return MEMIF_ERR_SUCCESS; /* 0 */
576 }
577 
578 /* slave -> master */
579 static_fn int
581 {
582  memif_msg_connect_t *cm = &msg->connect;
584  memif_list_elt_t elt;
585 
586  int err;
587  err = memif_connect1 (c);
588  if (err != MEMIF_ERR_SUCCESS)
589  return err;
590 
591  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
592  strlen ((char *) cm->if_name));
593 
594  int i;
595  if (c->on_interrupt != NULL)
596  {
597  for (i = 0; i < c->run_args.num_m2s_rings; i++)
598  {
599  elt.key = c->rx_queues[i].int_fd;
600  elt.data_struct = c;
602 
603  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
604  c->private_ctx);
605  }
606 
607  }
608 
609  c->on_connect ((void *) c, c->private_ctx);
610 
611  return err;
612 }
613 
614 /* master -> slave */
615 static_fn int
617 {
618  memif_msg_connect_t *cm = &msg->connect;
620 
621  int err;
622  err = memif_connect1 (c);
623  if (err != MEMIF_ERR_SUCCESS)
624  return err;
625 
626  strncpy ((char *) c->remote_if_name, (char *) cm->if_name,
627  strlen ((char *) cm->if_name));
628 
629  int i;
630  if (c->on_interrupt != NULL)
631  {
632  for (i = 0; i < c->run_args.num_s2m_rings; i++)
633  {
634  lm->control_fd_update (c->rx_queues[i].int_fd, MEMIF_FD_EVENT_READ,
635  c->private_ctx);
636  }
637  }
638 
639  c->on_connect ((void *) c, c->private_ctx);
640 
641  return err;
642 }
643 
644 static_fn int
646 {
648 
649  memset (c->remote_disconnect_string, 0,
650  sizeof (c->remote_disconnect_string));
651  strncpy ((char *) c->remote_disconnect_string, (char *) d->string,
652  strlen ((char *) d->string));
653 
654  /* on returning error, handle function will call memif_disconnect () */
655  DBG ("disconnect received: %s, mode: %d",
656  c->remote_disconnect_string, c->args.mode);
657  return MEMIF_ERR_DISCONNECT;
658 }
659 
660 static_fn int
662 {
663  char ctl[CMSG_SPACE (sizeof (int)) +
664  CMSG_SPACE (sizeof (struct ucred))] = { 0 };
665  struct msghdr mh = { 0 };
666  struct iovec iov[1];
667  memif_msg_t msg = { 0 };
668  ssize_t size;
669  int err = MEMIF_ERR_SUCCESS; /* 0 */
670  int fd = -1;
671  int i;
674  memif_socket_t *ms = NULL;
675  memif_list_elt_t *elt = NULL;
676 
677  iov[0].iov_base = (void *) &msg;
678  iov[0].iov_len = sizeof (memif_msg_t);
679  mh.msg_iov = iov;
680  mh.msg_iovlen = 1;
681  mh.msg_control = ctl;
682  mh.msg_controllen = sizeof (ctl);
683 
684  DBG ("recvmsg fd %d", ifd);
685  size = recvmsg (ifd, &mh, 0);
686  if (size != sizeof (memif_msg_t))
687  {
688  if (size == 0)
689  return MEMIF_ERR_DISCONNECTED;
690  else
691  return MEMIF_ERR_MFMSG;
692  }
693 
694  struct cmsghdr *cmsg;
695 
696  cmsg = CMSG_FIRSTHDR (&mh);
697  while (cmsg)
698  {
699  if (cmsg->cmsg_level == SOL_SOCKET)
700  {
701  if (cmsg->cmsg_type == SCM_CREDENTIALS)
702  {
703  /* Do nothing */ ;
704  }
705  else if (cmsg->cmsg_type == SCM_RIGHTS)
706  {
707  int *fdp = (int *) CMSG_DATA (cmsg);
708  fd = *fdp;
709  }
710  }
711  cmsg = CMSG_NXTHDR (&mh, cmsg);
712  }
713 
714  DBG ("Message type %u received", msg.type);
715 
716  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
717  if (elt != NULL)
718  c = (memif_connection_t *) elt->data_struct;
719 
720  switch (msg.type)
721  {
722  case MEMIF_MSG_TYPE_ACK:
723  break;
724 
726  if ((err = memif_msg_receive_hello (c, &msg)) != MEMIF_ERR_SUCCESS)
727  return err;
729  return err;
730  if ((err = memif_msg_enq_init (c)) != MEMIF_ERR_SUCCESS)
731  return err;
732  for (i = 0; i < c->regions_num; i++)
733  {
734  if ((err = memif_msg_enq_add_region (c, i)) != MEMIF_ERR_SUCCESS)
735  return err;
736  }
737  for (i = 0; i < c->run_args.num_s2m_rings; i++)
738  {
739  if ((err =
742  return err;
743  }
744  for (i = 0; i < c->run_args.num_m2s_rings; i++)
745  {
746  if ((err =
749  return err;
750  }
751  if ((err = memif_msg_enq_connect (c)) != MEMIF_ERR_SUCCESS)
752  return err;
753  break;
754 
755  case MEMIF_MSG_TYPE_INIT:
756  get_list_elt (&elt, lm->pending_list, lm->pending_list_len, ifd);
757  if (elt == NULL)
758  return -1;
759  ms = (memif_socket_t *) elt->data_struct;
760  if ((err = memif_msg_receive_init (ms, ifd, &msg)) != MEMIF_ERR_SUCCESS)
761  return err;
762  /* c->remote_pid = cr->pid */
763  /* c->remote_uid = cr->uid */
764  /* c->remote_gid = cr->gid */
765  get_list_elt (&elt, lm->control_list, lm->control_list_len, ifd);
766  if (elt == NULL)
767  return -1;
768  c = (memif_connection_t *) elt->data_struct;
769  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
770  return err;
771  break;
772 
774  if ((err =
776  return err;
777  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
778  return err;
779  break;
780 
782  if ((err =
784  return err;
785  if ((err = memif_msg_enq_ack (c)) != MEMIF_ERR_SUCCESS)
786  return err;
787  break;
788 
790  if ((err = memif_msg_receive_connect (c, &msg)) != MEMIF_ERR_SUCCESS)
791  return err;
792  if ((err = memif_msg_enq_connected (c)) != MEMIF_ERR_SUCCESS)
793  return err;
794  break;
795 
797  if ((err = memif_msg_receive_connected (c, &msg)) != MEMIF_ERR_SUCCESS)
798  return err;
799  break;
800 
802  if ((err = memif_msg_receive_disconnect (c, &msg)) != MEMIF_ERR_SUCCESS)
803  return err;
804  break;
805 
806  default:
807  return MEMIF_ERR_UNKNOWN_MSG;;
808  break;
809  }
810 
811  if (c != NULL)
812  c->flags |= MEMIF_CONNECTION_FLAG_WRITE;
813 
814  return MEMIF_ERR_SUCCESS; /* 0 */
815 }
816 
817 int
819 {
820  DBG ("connection fd error");
821  strncpy ((char *) c->remote_disconnect_string, "connection fd error", 19);
822  int err = memif_disconnect_internal (c);
823  return err;
824 }
825 
826 /* calls memif_msg_receive to handle pending messages on socket */
827 int
829 {
830  int err;
831  err = memif_msg_receive (c->fd);
832  if (err != 0)
833  {
834  err = memif_disconnect_internal (c);
835  }
836  return err;
837 }
838 
839 /* get msg from msg queue buffer and send it to socket */
840 int
842 {
844  int err = MEMIF_ERR_SUCCESS; /* 0 */
845 
846 
847  if ((c->flags & MEMIF_CONNECTION_FLAG_WRITE) == 0)
848  goto done;
849 
850  memif_msg_queue_elt_t *e = c->msg_queue;
851  if (e == NULL)
852  goto done;
853 
854  c->msg_queue = c->msg_queue->next;
855 
856  c->flags &= ~MEMIF_CONNECTION_FLAG_WRITE;
857 
858  err = memif_msg_send (c->fd, &e->msg, e->fd);
859  lm->free (e);
860  goto done;
861 
862 done:
863  return err;
864 }
865 
866 int
868 {
869  int addr_len;
870  struct sockaddr_un client;
871  int conn_fd;
873 
874  DBG ("accept called");
875 
876  addr_len = sizeof (client);
877  conn_fd =
878  accept (ms->fd, (struct sockaddr *) &client, (socklen_t *) & addr_len);
879 
880  if (conn_fd < 0)
881  {
882  return memif_syscall_error_handler (errno);
883  }
884  DBG ("accept fd %d", ms->fd);
885  DBG ("conn fd %d", conn_fd);
886 
887  memif_list_elt_t elt;
888  elt.key = conn_fd;
889  elt.data_struct = ms;
890 
891  add_list_elt (&elt, &lm->pending_list, &lm->pending_list_len);
893  ms->private_ctx);
894 
895  return memif_msg_send_hello (conn_fd);
896 }
897 
898 int
900 {
901  int err;
902 
903  err = memif_msg_receive (fd);
904 
905  return err;
906 }
static_fn int memif_msg_receive_disconnect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:645
memif_version_t max_version
Definition: memif.h:76
memif_interface_mode_t mode
Definition: memif.h:87
int memif_conn_fd_write_ready(memif_connection_t *c)
Definition: socket.c:841
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
Definition: socket.c:657
memif_msg_add_region_t add_region
Definition: memif.h:132
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
Definition: libmemif.h:89
#define MEMIF_SECRET_ERR
Definition: socket.h:29
Optimized string handling code, including c11-compliant "safe C library" variants.
uint8_t string[96]
Definition: memif.h:122
#define MEMIF_SLAVE_ERR
Definition: socket.h:26
#define NULL
Definition: clib.h:58
memif_msg_add_ring_t add_ring
Definition: memif.h:133
#define MEMIF_MSG_ADD_RING_FLAG_S2M
Definition: memif.h:101
#define MEMIF_MAX_REGION
Definition: private.h:29
memif_list_elt_t * pending_list
int memif_conn_fd_read_ready(memif_connection_t *c)
Definition: socket.c:828
int i
static_fn int memif_msg_send(int fd, memif_msg_t *msg, int afd)
Definition: socket.c:39
int memif_disconnect_internal(memif_connection_t *c)
Definition: main.c:1195
#define MEMIF_CONNECTION_FLAG_WRITE
memif_control_fd_update_t * control_fd_update
memif_region_index_t region
Definition: memif.h:103
memif_version_t min_version
Definition: memif.h:75
uint8_t secret[24]
Definition: memif.h:88
uint16_t private_hdr_size
Definition: memif.h:106
memif_list_elt_t * interface_list
memif_interface_id_t id
Definition: memif.h:86
uint8_t name[32]
Definition: memif.h:74
#define static_fn
Definition: socket.h:86
memif_realloc_t * realloc
memif_ring_index_t max_m2s_ring
Definition: memif.h:78
memif_free_t * free
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
Definition: memif.c:308
#define MEMIF_ID_ERR
Definition: socket.h:25
#define MEMIF_NOSECRET_ERR
Definition: socket.h:30
memif_region_offset_t offset
Definition: private.h:121
#define MEMIF_MAX_M2S_RING
Definition: private.h:27
memif_region_offset_t offset
Definition: memif.h:104
static_fn int memif_msg_receive_connect(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:580
#define MEMIF_MAX_LOG2_RING_SIZE
Definition: private.h:30
static_fn int memif_msg_receive_init(memif_socket_t *ms, int fd, memif_msg_t *msg)
Definition: socket.c:368
memif_msg_init_t init
Definition: memif.h:131
int memif_syscall_error_handler(int err_code)
Definition: main.c:204
memif_ring_index_t index
Definition: memif.h:102
memif_list_elt_t * interrupt_list
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
Definition: socket.c:198
vnet_crypto_main_t * cm
Definition: quic_crypto.c:41
uword size
#define MEMIF_CONN_ERR
Definition: socket.h:27
static_fn int memif_msg_enq_connected(memif_connection_t *c)
Definition: socket.c:286
static_fn int memif_msg_enq_init(memif_connection_t *c)
Definition: socket.c:125
#define MEMIF_FD_EVENT_DEL
if set, informs that fd is going to be closed (user may want to stop watching for events on this fd) ...
Definition: libmemif.h:94
memif_msg_disconnect_t disconnect
Definition: memif.h:136
struct memif_msg_queue_elt * next
static_fn int memif_msg_enq_ack(memif_connection_t *c)
Definition: socket.c:72
static_fn int memif_msg_send_hello(int fd)
Definition: socket.c:102
memif_msg_hello_t hello
Definition: memif.h:130
memif_log2_ring_size_t max_log2_ring_size
Definition: memif.h:80
int add_list_elt(memif_list_elt_t *e, memif_list_elt_t **list, uint16_t *len)
Definition: main.c:319
uint8_t if_name[32]
Definition: memif.h:111
uint8_t name[32]
Definition: memif.h:89
svmdb_client_t * c
uint8_t if_name[32]
Definition: memif.h:116
int get_list_elt(memif_list_elt_t **e, memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:355
memif_alloc_t * alloc
#define MEMIF_MODE_ERR
Definition: socket.h:28
#define DBG(...)
memif_region_index_t index
Definition: memif.h:94
int memif_read_ready(int fd)
Definition: socket.c:899
memif_log2_ring_size_t log2_ring_size
Definition: memif.h:105
memif_version_t version
Definition: memif.h:85
#define memif_min(a, b)
Definition: memif_private.h:54
memif_ring_index_t max_s2m_ring
Definition: memif.h:79
static_fn int memif_msg_enq_add_region(memif_connection_t *c, uint8_t region_index)
Definition: socket.c:167
memif_msg_connect_t connect
Definition: memif.h:134
#define MEMIF_VERSION
Definition: memif.h:28
uint16_t interrupt_list_len
static_fn int memif_msg_receive_add_ring(memif_connection_t *c, memif_msg_t *msg, int fd)
Definition: socket.c:518
static_fn int memif_msg_receive(int ifd)
Definition: socket.c:661
uint16_t flags
Definition: memif.h:100
static_fn int memif_msg_receive_add_region(memif_connection_t *c, memif_msg_t *msg, int fd)
Definition: socket.c:483
#define MEMIF_MAX_S2M_RING
Definition: private.h:28
uint8_t app_name[MEMIF_NAME_LEN]
memif_region_size_t size
Definition: memif.h:95
memif_region_index_t max_region
Definition: memif.h:77
memif_msg_type_t type
Definition: memif.h:127
uint16_t pending_list_len
memif_list_elt_t * control_list
static_fn int memif_msg_enq_connect(memif_connection_t *c)
Definition: socket.c:251
memif_log2_ring_size_t log2_ring_size
Definition: private.h:119
static_fn int memif_msg_receive_hello(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:342
memif_msg_connected_t connected
Definition: memif.h:135
uint16_t control_list_len
#define MEMIF_VER_ERR
Definition: socket.h:24
static_fn int memif_msg_receive_connected(memif_connection_t *c, memif_msg_t *msg)
Definition: socket.c:616
int memif_conn_fd_error(memif_connection_t *c)
Definition: socket.c:818
int memif_connect1(memif_connection_t *c)
Definition: main.c:1397
libmemif_main_t libmemif_main
Definition: main.c:68
int free_list_elt(memif_list_elt_t *list, uint16_t len, int key)
Definition: main.c:379
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:90
memif_get_external_region_addr_t * get_external_region_addr
memif_region_index_t region
Definition: private.h:120
static_fn int memif_msg_enq_add_ring(memif_connection_t *c, uint8_t index, uint8_t dir)
Definition: socket.c:204
uint16_t interface_list_len
memif_region_size_t region_size
Definition: private.h:103