aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-light/src/hicn/core/listener.h
blob: 76d865c5d19c01fac3f9662812315ad742f1ca13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * Copyright (c) 2021 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file listener.h
 * @brief hICN listeners
 */

#ifndef HICNLIGHT_LISTENER_H
#define HICNLIGHT_LISTENER_H

#include <hicn/face.h>

#include "address_pair.h"
#include "msgbuf.h"
#include <hicn/base/loop.h>

#define LISTENER_ID_UNDEFINED ~0

struct forwarder_s;

typedef struct {
  address_t address;
  face_type_t type;
} listener_key_t;

static inline int listener_key_equals(const listener_key_t *key1,
                                      const listener_key_t *key2) {
  return address_equals(&key1->address, &key2->address) &&
         (key1->type == key2->type);
}

/**
 * @brief Create a listener key starting from an address and a face type.
 *
 * @param address
 * @param type
 * @return listener_key_t The listener key created.
 *
 * @note The listener key returned is resetted before intializing
 * the internal fields, to allow a reliable hash generation.
 */
listener_key_t listener_key_factory(address_t address, face_type_t type);

/* This structure holds what is in common to all listeners */
typedef struct {
  int id;
  char *name;
  union {
    listener_key_t key;
    struct {
      address_t address;
      face_type_t type;
    };
  };

  char *interface_name;
  unsigned family;

  int fd;
  event_t *event_data;

  void *data; /* Listener specific data */
  struct forwarder_s *forwarder;
} listener_t;

#define listener_get_id(L) ((L)->id)
#define listener_get_name(L) ((L)->name)
#define listener_get_key(L) (&(L)->key)
#define listener_get_type(L) ((L)->type)
#define listener_get_interface_name(L) ((L)->interface_name)
#define listener_get_address(L) (&(L)->address)
#define listener_has_valid_type(L) (face_type_is_valid((L)->type))
#define listener_id_is_valid(ID) (ID != LISTENER_ID_UNDEFINED)

listener_t *listener_create(face_type_t type, const address_t *address,
                            const char *interface_name, const char *symbolic,
                            struct forwarder_s *forwarder);

/**
 * @brief Helper function used inside 'listener_create' to
 * setup variables in listener struct.
 *
 * @see listener_create
 */
int listener_initialize(listener_t *listener, face_type_t type,
                        const char *name, unsigned listener_id,
                        const address_t *address, const char *interface_name,
                        struct forwarder_s *forwarder);

int listener_finalize(listener_t *listener);

int listener_punt(const listener_t *listener, const char *prefix_s);

int listener_get_socket(const listener_t *listener, const address_t *local,
                        const address_t *remote, const char *interface_name);

unsigned listener_create_connection(listener_t *listener, const char *name,
                                    const address_pair_t *pair);

void listener_setup_local(struct forwarder_s *forwarder, uint16_t port);

void listener_process_packet(const listener_t *listener, const uint8_t *packet,
                             size_t size);

ssize_t listener_read_single(listener_t *listener, int fd,
                             unsigned connection_id);
ssize_t listener_read_batch(listener_t *listener, int fd,
                            unsigned connection_id);

/**
 * @brief Callback helper function for batch reading data from listener fd.
 *
 * This function is usually called from the listener read callback to proceed to
 * actual reading of data from the fd.
 *
 * @see listener_read_callback
 *
 * NOTE: the function returns size_t as for TCP we might need to know how much
 * data we can consume from the socket.
 */
ssize_t listener_read_callback(listener_t *listener, int fd,
                               unsigned connection_id, void *user_data);

#define listener_get_forwarder(listener) (listener->forwarder)
#define listener_get_fd(listener) (listener->fd)

#endif /* HICNLIGHT_LISTENER_H */