Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions
route.c File Reference

sip_route functions More...

#include "asterisk.h"
#include "asterisk/utils.h"
#include "include/route.h"
#include "include/reqresp_parser.h"
Include dependency graph for route.c:

Go to the source code of this file.

Data Structures

struct  sip_route_hop
 Structure to save a route hop. More...
 

Macros

#define sip_route_first(route)   AST_LIST_FIRST(&(route)->list)
 
#define sip_route_traverse(route, elem)   AST_LIST_TRAVERSE(&(route)->list, elem, list)
 Traverse route hops. More...
 

Functions

const char * sip_route_add (struct sip_route *route, const char *uri, size_t len, int inserthead)
 Add a new hop to the route. More...
 
void sip_route_clear (struct sip_route *route)
 Free all routes in the list. More...
 
void sip_route_copy (struct sip_route *dst, const struct sip_route *src)
 copy route-set More...
 
void sip_route_dump (const struct sip_route *route)
 Verbose dump of all hops for debugging. More...
 
const char * sip_route_first_uri (const struct sip_route *route)
 Get the URI of the route's first hop. More...
 
int sip_route_is_strict (struct sip_route *route)
 Check if the route is strict. More...
 
struct ast_strsip_route_list (const struct sip_route *route, int formatcli, int skip)
 Make the comma separated list of route hops. More...
 
void sip_route_process_header (struct sip_route *route, const char *header, int inserthead)
 Add routes from header. More...
 

Detailed Description

sip_route functions

Definition in file route.c.

Macro Definition Documentation

◆ sip_route_first

#define sip_route_first (   route)    AST_LIST_FIRST(&(route)->list)

Definition at line 37 of file route.c.

Referenced by sip_route_first_uri(), and sip_route_is_strict().

◆ sip_route_traverse

#define sip_route_traverse (   route,
  elem 
)    AST_LIST_TRAVERSE(&(route)->list, elem, list)

Traverse route hops.

Definition at line 36 of file route.c.

Referenced by sip_route_copy(), sip_route_dump(), and sip_route_list().

Function Documentation

◆ sip_route_add()

const char* sip_route_add ( struct sip_route route,
const char *  uri,
size_t  len,
int  inserthead 
)

Add a new hop to the route.

Parameters
routeRoute
uriAddress of this hop
lenLength of hop not including null terminator
insertheadIf true then inserted the new route to the top of the list
Return values
Pointerto null terminated copy of URI on success
NULLon error

Definition at line 47 of file route.c.

References ast_copy_string(), AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, ast_malloc, sip_route_hop::list, sip_route::list, sip_route_hop::next, NULL, route_invalidated, sip_route_empty, sip_route::type, and sip_route_hop::uri.

Referenced by build_route(), sip_route_copy(), and sip_route_process_header().

48 {
49  struct sip_route_hop *hop;
50 
51  if (!uri || len < 1 || uri[0] == '\0') {
52  return NULL;
53  }
54 
55  /* Expand len to include null terminator */
56  len++;
57 
58  /* ast_calloc is not needed because all fields are initialized in this block */
59  hop = ast_malloc(sizeof(struct sip_route_hop) + len);
60  if (!hop) {
61  return NULL;
62  }
63  ast_copy_string(hop->uri, uri, len);
64 
65  if (inserthead) {
66  AST_LIST_INSERT_HEAD(&route->list, hop, list);
67  route->type = route_invalidated;
68  } else {
69  if (sip_route_empty(route)) {
70  route->type = route_invalidated;
71  }
72  AST_LIST_INSERT_TAIL(&route->list, hop, list);
73  hop->list.next = NULL;
74  }
75 
76  return hop->uri;
77 }
#define NULL
Definition: resample.c:96
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
Structure to save a route hop.
Definition: route.c:42
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct sip_route_hop::@180 list
enum sip_route_type type
Definition: route.h:49
struct sip_route_hop * next
Definition: route.c:43
struct sip_route::@165 list
char uri[0]
Definition: route.c:44

◆ sip_route_clear()

void sip_route_clear ( struct sip_route route)

Free all routes in the list.

Definition at line 132 of file route.c.

References ast_free, AST_LIST_REMOVE_HEAD, sip_route_hop::list, sip_route::list, route_loose, and sip_route::type.

Referenced by build_path(), build_route(), sip_destroy_peer(), sip_pvt_dtor(), and sip_route_copy().

133 {
134  struct sip_route_hop *hop;
135 
136  while ((hop = AST_LIST_REMOVE_HEAD(&route->list, list))) {
137  ast_free(hop);
138  }
139 
140  route->type = route_loose;
141 }
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
Structure to save a route hop.
Definition: route.c:42
#define ast_free(a)
Definition: astmm.h:182
struct sip_route_hop::@180 list
enum sip_route_type type
Definition: route.h:49
struct sip_route::@165 list

◆ sip_route_copy()

void sip_route_copy ( struct sip_route dst,
const struct sip_route src 
)

copy route-set

Return values
non-zeroon failure
0on success

Definition at line 115 of file route.c.

References ast_debug, sip_route_add(), sip_route_clear(), sip_route_traverse, sip_route::type, and sip_route_hop::uri.

Referenced by create_addr_from_peer(), and sip_poke_peer().

116 {
117  struct sip_route_hop *hop;
118 
119  /* make sure dst is empty */
120  sip_route_clear(dst);
121 
122  sip_route_traverse(src, hop) {
123  const char *uri = sip_route_add(dst, hop->uri, strlen(hop->uri), 0);
124  if (uri) {
125  ast_debug(2, "sip_route_copy: copied hop: <%s>\n", uri);
126  }
127  }
128 
129  dst->type = src->type;
130 }
#define sip_route_traverse(route, elem)
Traverse route hops.
Definition: route.c:36
const char * sip_route_add(struct sip_route *route, const char *uri, size_t len, int inserthead)
Add a new hop to the route.
Definition: route.c:47
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
void sip_route_clear(struct sip_route *route)
Free all routes in the list.
Definition: route.c:132
Structure to save a route hop.
Definition: route.c:42
enum sip_route_type type
Definition: route.h:49
char uri[0]
Definition: route.c:44

◆ sip_route_dump()

void sip_route_dump ( const struct sip_route route)

Verbose dump of all hops for debugging.

Definition at line 143 of file route.c.

References ast_verbose(), sip_route_empty, sip_route_traverse, and sip_route_hop::uri.

Referenced by build_path(), and build_route().

144 {
145  if (sip_route_empty(route)) {
146  ast_verbose("sip_route_dump: no route/path\n");
147  } else {
148  struct sip_route_hop *hop;
149  sip_route_traverse(route, hop) {
150  ast_verbose("sip_route_dump: route/path hop: <%s>\n", hop->uri);
151  }
152  }
153 }
#define sip_route_traverse(route, elem)
Traverse route hops.
Definition: route.c:36
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
#define sip_route_empty(route)
Check if route has no URI&#39;s.
Definition: route.h:118
Structure to save a route hop.
Definition: route.c:42
char uri[0]
Definition: route.c:44

◆ sip_route_first_uri()

const char* sip_route_first_uri ( const struct sip_route route)

Get the URI of the route's first hop.

Definition at line 199 of file route.c.

References NULL, sip_route_first, and sip_route_hop::uri.

Referenced by build_route(), create_addr_from_peer(), reqprep(), and sip_poke_peer().

200 {
201  struct sip_route_hop *hop = sip_route_first(route);
202  return hop ? hop->uri : NULL;
203 }
#define NULL
Definition: resample.c:96
#define sip_route_first(route)
Definition: route.c:37
Structure to save a route hop.
Definition: route.c:42
char uri[0]
Definition: route.c:44

◆ sip_route_is_strict()

int sip_route_is_strict ( struct sip_route route)

Check if the route is strict.

Note
The result is cached in route->type

Definition at line 183 of file route.c.

References NULL, route_invalidated, route_loose, route_strict, sip_route_first, sip_route::type, and sip_route_hop::uri.

Referenced by build_path(), build_route(), and reqprep().

184 {
185  if (!route) {
186  return 0;
187  }
188 
189  if (route->type == route_invalidated) {
190  struct sip_route_hop *hop = sip_route_first(route);
191  int ret = hop && (strstr(hop->uri, ";lr") == NULL);
192  route->type = ret ? route_strict : route_loose;
193  return ret;
194  }
195 
196  return (route->type == route_strict) ? 1 : 0;
197 }
#define NULL
Definition: resample.c:96
#define sip_route_first(route)
Definition: route.c:37
Structure to save a route hop.
Definition: route.c:42
enum sip_route_type type
Definition: route.h:49
char uri[0]
Definition: route.c:44

◆ sip_route_list()

struct ast_str* sip_route_list ( const struct sip_route route,
int  formatcli,
int  skip 
)

Make the comma separated list of route hops.

Parameters
routeSource of route list
formatcliAdd's space after comma's, print's N/A if list is empty.
skipNumber of hops to skip
Return values
anallocated struct ast_str on success
NULLon failure

Definition at line 155 of file route.c.

References ast_str_append(), ast_str_create, buf, NULL, sip_route_traverse, and sip_route_hop::uri.

Referenced by _sip_show_peer(), add_route(), parse_register_contact(), sip_show_channel(), and update_peer().

156 {
157  struct sip_route_hop *hop;
158  const char *comma;
159  struct ast_str *buf;
160  int i = 0 - skip;
161 
162  buf = ast_str_create(64);
163  if (!buf) {
164  return NULL;
165  }
166 
167  comma = formatcli ? ", " : ",";
168 
169  sip_route_traverse(route, hop) {
170  if (i >= 0) {
171  ast_str_append(&buf, 0, "%s<%s>", i ? comma : "", hop->uri);
172  }
173  i++;
174  }
175 
176  if (formatcli && i <= 0) {
177  ast_str_append(&buf, 0, "N/A");
178  }
179 
180  return buf;
181 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define sip_route_traverse(route, elem)
Traverse route hops.
Definition: route.c:36
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define NULL
Definition: resample.c:96
Structure to save a route hop.
Definition: route.c:42
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
char uri[0]
Definition: route.c:44
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ sip_route_process_header()

void sip_route_process_header ( struct sip_route route,
const char *  header,
int  inserthead 
)

Add routes from header.

Note
This procedure is for headers that require use of <brackets>.

Definition at line 79 of file route.c.

References ast_debug, ast_do_crash(), ast_log, get_in_brackets_const(), len(), LOG_ERROR, NULL, sip_route_add(), and sip_route_hop::uri.

Referenced by build_path(), and build_route().

80 {
81  const char *hop;
82  int len = 0;
83  const char *uri;
84 
85  if (!route) {
86  ast_log(LOG_ERROR, "sip_route_process_header requires non-null route");
87  ast_do_crash();
88  return;
89  }
90 
91  while (!get_in_brackets_const(header, &uri, &len)) {
92  header = strchr(header, ',');
93  if (header >= uri && header <= (uri + len)) {
94  /* comma inside brackets */
95  const char *next_br = strchr(header, '<');
96  if (next_br && next_br <= (uri + len)) {
97  header++;
98  continue;
99  }
100  continue;
101  }
102  if ((hop = sip_route_add(route, uri, len, inserthead))) {
103  ast_debug(2, "sip_route_process_header: <%s>\n", hop);
104  }
105  header = strchr(uri + len + 1, ',');
106  if (header == NULL) {
107  /* No more field-values, we're done with this header */
108  break;
109  }
110  /* Advance past comma */
111  header++;
112  }
113 }
const char * sip_route_add(struct sip_route *route, const char *uri, size_t len, int inserthead)
Add a new hop to the route.
Definition: route.c:47
#define NULL
Definition: resample.c:96
int get_in_brackets_const(const char *src, const char **start, int *length)
Get text in brackets on a const without copy.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void DO_CRASH_NORETURN ast_do_crash(void)
Force a crash if DO_CRASH is defined.
Definition: main/utils.c:2552