Project Alice
Loading...
Searching...
No Matches
pcp.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2014 by Cisco Systems, Inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 1. Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef PCP_H
27#define PCP_H
28
29#ifdef WIN32
30#include <winsock2.h>
31#include <in6addr.h>
32#include <ws2tcpip.h>
33#include <time.h>
34#if !defined ssize_t && defined _MSC_VER
35//typedef int ssize_t;
36#endif
37#else //WIN32
38#include <sys/time.h>
39#include <sys/socket.h>
40#include <netinet/in.h>
41#endif
42
43#include <stdint.h>
44
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49#ifdef PCP_SOCKET_IS_VOIDPTR
50#define PCP_SOCKET void *
51#else //PCP_SOCKET_IS_VOIDPTR
52#ifdef WIN32
53#define PCP_SOCKET SOCKET
54#else //WIN32
55#define PCP_SOCKET int
56#endif //WIN32
57#endif //PCP_SOCKET_IS_VOIDPTR
58
59#ifdef PCP_EXPERIMENTAL
60typedef struct pcp_userid_option *pcp_userid_option_p;
61typedef struct pcp_deviceid_option *pcp_deviceid_option_p;
62typedef struct pcp_location_option *pcp_location_option_p;
63#endif //PCP_EXPERIMENTAL
64
65typedef enum {
82
83/* DEBUG levels */
84typedef enum {
92
93typedef void (*external_logger)(pcp_loglvl_e, const char *);
94
96
97// runtime level of logging
99
100typedef struct pcp_flow_s pcp_flow_t;
101typedef struct pcp_ctx_s pcp_ctx_t;
102
103typedef struct pcp_socket_vt_s {
104 PCP_SOCKET (*sock_create)(int domain, int type, int protocol);
105 int (*sock_recvfrom)(PCP_SOCKET sockfd, void *buf, size_t len,
106 int flags, struct sockaddr *src_addr, socklen_t *addrlen);
107 int (*sock_sendto)(PCP_SOCKET sockfd, const void *buf, size_t len,
108 int flags, struct sockaddr *dest_addr, socklen_t addrlen);
109 int (*sock_close)(PCP_SOCKET sockfd);
111
112/*
113 * Initialize library, optionally initiate auto-discovery of PCP servers
114 * autodiscovery - enable/disable auto-discovery of PCP servers
115 * socket_vt - optional - virt. table to override default socket functions.
116 * Pointer has to be valid until pcp_terminate is called.
117 * Pass NULL to use default socket functions
118 * return value - pcp context used in other functions.
119 */
120#define ENABLE_AUTODISCOVERY 1
121#define DISABLE_AUTODISCOVERY 0
122pcp_ctx_t *pcp_init(uint8_t autodiscovery, pcp_socket_vt_t *socket_vt);
123
124//returns internal pcp server ID, -1 => error occurred
125int pcp_add_server(pcp_ctx_t *ctx, struct sockaddr *pcp_server,
126 uint8_t pcp_version);
127
128/*
129 * Close socket fds and clean up all settings, frees all library buffers
130 * close_flows - signal end of flows to PCP servers
131 */
132void pcp_terminate(pcp_ctx_t *ctx, int close_flows);
133
135// Flow API
136
137/*
138 * Creates new PCP message from parameters parsed to this function:
139 * src_addr source IP/port
140 * dst_addr destination IP/port - optional
141 * ext_addr sugg. ext. IP/port - optional
142 * protocol protocol associated with flow
143 * lifetime time in seconds how long should mapping last
144 * userdata pointer to user data associated with a new flow
145 *
146 * return value
147 * pcp_flow_t *used in other functions to reference this flow.
148 */
149pcp_flow_t *pcp_new_flow(pcp_ctx_t *ctx, struct sockaddr *src_addr,
150 struct sockaddr *dst_addr, struct sockaddr *ext_addr, uint8_t protocol,
151 uint32_t lifetime, void *userdata);
152
153void pcp_flow_set_lifetime(pcp_flow_t *f, uint32_t lifetime);
154
155/*
156 * Store pointer to application's user data associated with a flow. Pointer can
157 * be read by function pcp_flow_get_user_data. Arguments:
158 * f flow - to which store application's user data.
159 * userdata pointer to user data to be stored along a flow
160 */
161void pcp_flow_set_user_data(pcp_flow_t *f, void *userdata);
162
163/*
164 * Get a pointer to application's user data associated with the flow, previously
165 * stored by pcp_flow_set_user_data, or pcp_new_flow. Arguments:
166 * f flow - to which store application's user data.
167 *
168 * return
169 * void * pointer to user data to be stored along a flow
170 */
172
173/*
174 * Set 3rd party option to the existing message flow info.
175 */
176void pcp_flow_set_3rd_party_opt(pcp_flow_t *f, struct sockaddr *thirdp_addr);
177
178#ifdef PCP_FLOW_PRIORITY
179/*
180 * Set PCP's flow priority option to the flow, causing a router to start
181 * altering IP packets' DSCP field to dscp_up in up direction and to dscp_down
182 * for down direction.
183 */
184void pcp_flow_set_flowp(pcp_flow_t *f, uint8_t dscp_up, uint8_t dscp_down);
185#endif
186
187#ifdef PCP_EXPERIMENTAL
188/*
189 * Append metadata option to the existing flow f
190 * if exists md with given id then replace with new value
191 * if value is NULL then remove metadata with this id
192 */
193void pcp_flow_add_md(pcp_flow_t *f, uint32_t md_id, void *value, size_t val_len);
194
195int pcp_flow_set_userid(pcp_flow_t *f, pcp_userid_option_p userid);
196int pcp_flow_set_deviceid(pcp_flow_t *f, pcp_deviceid_option_p dev);
197int pcp_flow_set_location(pcp_flow_t *f, pcp_location_option_p loc);
198#endif
199
200/*
201 * Append filter option.
202 */
203void pcp_flow_set_filter_opt(pcp_flow_t *f, struct sockaddr *filter_ip,
204 uint8_t filter_prefix);
205
206/*
207 * Append prefer failure option.
208 */
210
211#ifdef PCP_SADSCP
212/*
213 * create new PCP message with SADSCP opcode. It's used to learn
214 * correct DSCP values to get desired flow treatment by router.
215 */
216pcp_flow_t *pcp_learn_dscp(pcp_ctx_t *ctx, uint8_t delay_tol, uint8_t loss_tol,
217 uint8_t jitter_tol, char *app_name);
218#endif
219
220/*
221 * Remove flow from PCP server. Sends a PCP message with lifetime set to 0
222 * to PCP server.
223 */
225
226/*
227 * Frees memory pointed to by f; Invalidates f.
228 */
230
231typedef enum {
238
239typedef struct pcp_flow_info {
241 struct in6_addr pcp_server_ip;
242 struct in6_addr ext_ip;
243 uint16_t ext_port; //network byte order
247 struct in6_addr int_ip;
248 uint16_t int_port; //network byte order
249 struct in6_addr dst_ip;
250 uint16_t dst_port; //network byte order
252 uint8_t learned_dscp; //relevant only for flow created by pcp_learn_dscp
254
255// Allocates info_buf by malloc, has to be freed by client when no longer needed.
256pcp_flow_info_t *pcp_flow_get_info(pcp_flow_t *f, size_t *info_count);
257
258//callback function type - called when flow state has changed
259typedef void (*pcp_flow_change_notify)(pcp_flow_t *f, struct sockaddr *src_addr,
260 struct sockaddr *ext_addr, pcp_fstate_e, void *cb_arg);
261
262//set flow state change notify callback function
264 void *cb_arg);
265
266/* evaluate flow state
267 * params:
268 * flow (in) - handle of the flow
269 * fstate (out) - state of the flow
270 * return value - count of interfaces in exit_state (nonzero value means
271 * there is some result from PCP server)
272 */
274
276// Event handling functions
277
278/*
279 * pcp_pulse - handle socket and timeout events. It's intended to be
280 * used in select loop.
281 * params:
282 * pcp_ctx_t *ctx - pcp context obtained by pcp_init
283 * next_timeout(in/out) - nearest time-out. if it is filled by nonzero
284 * value it will return smaller one of provided and
285 * inner calculated. to be used in select function
286 */
287int pcp_pulse(pcp_ctx_t *ctx, struct timeval *next_timeout);
288
289/*
290 * Get socket used to communicate with PCP server.
291 */
293
294//example of pcp_pulse and pcp_get_socket use in select loop:
295/*
296 pcp_ctx_t *ctx=pcp_init(1, NULL);
297 int sock=pcp_get_socket(ctx);
298 pcp_flow_t f=pcp_new_flow(ctx,...);
299 fd_set rfds;
300 do {
301 struct timeval tv={0, 0};
302 FD_ZERO(&rfds);
303 FD_SET(sock, &rfds);
304 pcp_pulse(ctx, &tv);
305 select(sock+1, &rfds, NULL, NULL, &tv);
306 } while (1);
307 */
308
310// Blocking wait for flow reaching one of exit states or time-out(ms)
311// expiration.
312/* pcp_wait
313 * params:
314 * flow (in) - pcp flow handle
315 * timeout (in) - maximal time in ms to wait for result
316 * exit_on_partial_res (in) - do not wait for result of all interfaces or
317 * possible PCP servers. Instead return immediately
318 * after first received result.
319 */
320pcp_fstate_e pcp_wait(pcp_flow_t *flow, int timeout, int exit_on_partial_res);
321
322// example of pcp_wait use:
323/*
324 pcp_flow_t f=pcp_new_flow(ctx, (struct sockaddr *)&src,
325 (struct sockaddr *)&dst, NULL, IPPROTO_TCP, 60, NULL);
326 pcp_flow_set_flowp(f, 12, 16);
327 pcp_wait(f, 500, 0); // send PCP msg and wait for response for 500 ms
328 */
329
330#ifdef __cplusplus
331}
332#endif /* __cplusplus */
333
334#endif /* PCP_H */
uint uint32_t
uchar uint8_t
int pcp_add_server(pcp_ctx_t *ctx, struct sockaddr *pcp_server, uint8_t pcp_version)
Definition: pcp_api.c:72
pcp_loglvl_e pcp_log_level
Definition: pcp_logger.c:48
int pcp_eval_flow_state(pcp_flow_t *flow, pcp_fstate_e *fstate)
Definition: pcp_api.c:136
void(* external_logger)(pcp_loglvl_e, const char *)
Definition: pcp.h:93
void pcp_flow_set_filter_opt(pcp_flow_t *f, struct sockaddr *filter_ip, uint8_t filter_prefix)
Definition: pcp_api.c:511
pcp_ctx_t * pcp_init(uint8_t autodiscovery, pcp_socket_vt_t *socket_vt)
Definition: pcp_api.c:93
void * pcp_flow_get_user_data(pcp_flow_t *f)
Definition: pcp_api.c:745
void pcp_flow_set_user_data(pcp_flow_t *f, void *userdata)
Definition: pcp_api.c:735
void pcp_set_loggerfn(external_logger ext_log)
Definition: pcp_logger.c:107
pcp_loglvl_e
Definition: pcp.h:84
@ PCP_LOGLVL_ERR
Definition: pcp.h:86
@ PCP_LOGLVL_NONE
Definition: pcp.h:85
@ PCP_LOGLVL_DEBUG
Definition: pcp.h:90
@ PCP_LOGLVL_INFO
Definition: pcp.h:88
@ PCP_LOGLVL_PERR
Definition: pcp.h:89
@ PCP_LOGLVL_WARN
Definition: pcp.h:87
pcp_fstate_e pcp_wait(pcp_flow_t *flow, int timeout, int exit_on_partial_res)
Definition: pcp_api.c:187
void pcp_set_flow_change_cb(pcp_ctx_t *ctx, pcp_flow_change_notify cb_fun, void *cb_arg)
void(* pcp_flow_change_notify)(pcp_flow_t *f, struct sockaddr *src_addr, struct sockaddr *ext_addr, pcp_fstate_e, void *cb_arg)
Definition: pcp.h:259
struct pcp_socket_vt_s pcp_socket_vt_t
void pcp_delete_flow(pcp_flow_t *f)
Definition: pcp_api.c:639
void pcp_close_flow(pcp_flow_t *f)
Definition: pcp_api.c:626
void pcp_flow_set_3rd_party_opt(pcp_flow_t *f, struct sockaddr *thirdp_addr)
Definition: pcp_api.c:500
pcp_flow_t * pcp_new_flow(pcp_ctx_t *ctx, struct sockaddr *src_addr, struct sockaddr *dst_addr, struct sockaddr *ext_addr, uint8_t protocol, uint32_t lifetime, void *userdata)
Definition: pcp_api.c:389
#define PCP_SOCKET
Definition: pcp.h:55
struct pcp_flow_info pcp_flow_info_t
void pcp_flow_set_prefer_failure_opt(pcp_flow_t *f)
Definition: pcp_api.c:526
PCP_SOCKET pcp_get_socket(pcp_ctx_t *ctx)
Definition: pcp_api.c:66
pcp_fstate_e
Definition: pcp.h:231
@ pcp_state_short_lifetime_error
Definition: pcp.h:235
@ pcp_state_partial_result
Definition: pcp.h:234
@ pcp_state_failed
Definition: pcp.h:236
@ pcp_state_succeeded
Definition: pcp.h:233
@ pcp_state_processing
Definition: pcp.h:232
void pcp_flow_set_lifetime(pcp_flow_t *f, uint32_t lifetime)
Definition: pcp_api.c:489
pcp_flow_info_t * pcp_flow_get_info(pcp_flow_t *f, size_t *info_count)
Definition: pcp_api.c:669
int pcp_pulse(pcp_ctx_t *ctx, struct timeval *next_timeout)
pcp_errno
Definition: pcp.h:65
@ PCP_ERR_SUCCESS
Definition: pcp.h:66
@ PCP_ERR_SHORT_LIFETIME_ERR
Definition: pcp.h:76
@ PCP_ERR_NO_MEM
Definition: pcp.h:73
@ PCP_ERR_OPT_ALREADY_PRESENT
Definition: pcp.h:68
@ PCP_ERR_TIMEOUT
Definition: pcp.h:77
@ PCP_ERR_ADDRINUSE
Definition: pcp.h:80
@ PCP_ERR_WOULDBLOCK
Definition: pcp.h:79
@ PCP_ERR_RECV_FAILED
Definition: pcp.h:71
@ PCP_ERR_BAD_ARGS
Definition: pcp.h:74
@ PCP_ERR_UNKNOWN
Definition: pcp.h:75
@ PCP_ERR_NOT_FOUND
Definition: pcp.h:78
@ PCP_ERR_SEND_FAILED
Definition: pcp.h:70
@ PCP_ERR_BAD_AFINET
Definition: pcp.h:69
@ PCP_ERR_UNSUP_VERSION
Definition: pcp.h:72
@ PCP_ERR_MAX_SIZE
Definition: pcp.h:67
void pcp_terminate(pcp_ctx_t *ctx, int close_flows)
Definition: pcp_api.c:662
uint8_t learned_dscp
Definition: pcp.h:252
uint16_t dst_port
Definition: pcp.h:250
struct in6_addr int_ip
Definition: pcp.h:247
struct in6_addr dst_ip
Definition: pcp.h:249
pcp_fstate_e result
Definition: pcp.h:240
struct in6_addr pcp_server_ip
Definition: pcp.h:241
time_t recv_lifetime_end
Definition: pcp.h:244
uint16_t int_port
Definition: pcp.h:248
time_t lifetime_renew_s
Definition: pcp.h:245
uint8_t protocol
Definition: pcp.h:251
uint16_t ext_port
Definition: pcp.h:243
struct in6_addr ext_ip
Definition: pcp.h:242
uint8_t pcp_result_code
Definition: pcp.h:246
PCP_SOCKET(* sock_create)(int domain, int type, int protocol)
Definition: pcp.h:104
int(* sock_recvfrom)(PCP_SOCKET sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
Definition: pcp.h:105
int(* sock_close)(PCP_SOCKET sockfd)
Definition: pcp.h:109
int(* sock_sendto)(PCP_SOCKET sockfd, const void *buf, size_t len, int flags, struct sockaddr *dest_addr, socklen_t addrlen)
Definition: pcp.h:107