17 #include <sipwitch-config.h>
18 #include <ucommon/secure.h>
19 #include <ucommon/export.h>
28 #if defined(__APPLE__) && defined(__MACH__)
29 #include <arpa/nameser_compat.h>
35 #define MAXPACKET PACKETSZ
37 #define MAXPACKET 1024
81 while(index <
count) {
83 if(current > prior && current < next)
94 while(index <
count) {
95 if(
srvlist[index].priority == priority) {
103 struct sockaddr *
srv::find(uint16_t priority, uint32_t weight)
108 while(index <
count) {
109 if(
srvlist[index].priority == priority) {
111 if(total >= weight) {
122 int protocol = IPPROTO_UDP;
124 char host[256], svc[10];
125 struct addrinfo hint;
128 protocol = IPPROTO_TCP;
130 #if defined(HAVE_RESOLV_H)
136 String::set(svc,
sizeof(svc),
"sip");
142 snprintf(svc,
sizeof(svc),
"%d", port);
144 else if(eq(uri,
"sips:", 5)) {
145 protocol = IPPROTO_TCP;
146 String::set(svc,
sizeof(svc),
"sips");
148 else if(eq(uri,
"tcp:", 4)) {
149 protocol = IPPROTO_TCP;
152 else if(eq(uri,
"udp:", 4)) {
153 protocol = IPPROTO_UDP;
158 memset(&hint, 0,
sizeof(hint));
160 hint.ai_socktype = 0;
161 hint.ai_protocol = protocol;
163 if(hint.ai_protocol == IPPROTO_UDP)
164 hint.ai_socktype = SOCK_DGRAM;
166 hint.ai_socktype = SOCK_STREAM;
169 hint.ai_flags = AI_PASSIVE;
172 if(Socket::is_numeric(host)) {
173 hint.ai_flags |= AI_NUMERICHOST;
181 #if defined(AF_INET6) && defined(AI_V4MAPPED)
182 if(hint.ai_family == AF_INET6)
183 hint.ai_flags |= AI_V4MAPPED;
185 #ifdef AI_NUMERICSERV
187 hint.ai_flags |= AI_NUMERICSERV;
192 srvlist = cb->resolve(uri, &hint);
206 uint16_t acount, qcount;
207 unsigned char *mp, *ep, *cp;
208 uint16_t type, weight, priority, hport, dlen;
217 if(hint.ai_protocol == IPPROTO_TCP)
218 snprintf(zone,
sizeof(zone),
"_%s._tcp.%s", svc, host);
220 snprintf(zone,
sizeof(zone),
"_%s._udp.%s", svc, host);
222 result = res_query(zone, C_IN, T_SRV, (
unsigned char *)&reply,
sizeof(reply));
223 if(result < (
int)
sizeof(HEADER))
226 hp = (HEADER *)&reply;
227 acount = ntohs(hp->ancount);
228 qcount = ntohs(hp->qdcount);
229 mp = (
unsigned char *)&reply;
230 ep = (
unsigned char *)&reply + result;
231 cp = (
unsigned char *)&reply +
sizeof(HEADER);
237 while(qcount-- > 0 && cp < ep) {
238 result = dn_expand(mp, ep, cp, hbuf,
sizeof(hbuf));
241 cp += result + QFIXEDSZ;
244 while(acount-- > 0 && cp < ep) {
245 result = dn_expand(mp, ep, cp, hbuf,
sizeof(hbuf));
251 type = ntohs(*((uint16_t *)cp));
252 cp +=
sizeof(uint16_t);
255 cp +=
sizeof(uint16_t);
258 cp +=
sizeof(uint32_t);
260 dlen = ntohs(*((uint16_t *)cp));
261 cp +=
sizeof(uint16_t);
268 priority = ntohs(*((uint16_t *)cp));
269 cp +=
sizeof(uint16_t);
271 weight = ntohs(*((uint16_t *)cp));
272 cp +=
sizeof(uint16_t);
274 hport = ntohs(*((uint16_t *)cp));
275 cp +=
sizeof(uint16_t);
277 result = dn_expand(mp, ep, cp, hbuf,
sizeof(hbuf));
281 Socket::address resolv(hbuf, hport);
282 const struct sockaddr *sp = resolv.getAddr();
287 Random::fill((
unsigned char *)&rand,
sizeof(rand));
290 weight = (1 + rand) % ( 10000 * weight);
295 if(!current || priority < current->priority || weight > current->
weight) {
314 String::set(svc,
sizeof(svc),
"5061");
315 else if(eq(svc,
"sip"))
316 String::set(svc,
sizeof(svc),
"5060");
317 getaddrinfo(host, svc, &hint, &list);
318 struct addrinfo *ap = list;
356 while(index <
count) {
358 if(np->priority <
pri)
378 const char *schema =
"sip";
379 const char *sid = uri;
386 if(eq(uri,
"sips:", 5)) {
390 else if(eq(uri,
"tcp:", 4)) {
393 else if(eq(uri,
"udp:", 4)) {
398 char *cp = strrchr(host,
'.');
399 if(Socket::is_numeric(host) || !cp || eq(cp,
".local") || eq(cp,
".localdomain")) {
401 if(eq(schema,
"sips"))
406 if(strchr(host,
':'))
407 snprintf(buf, size,
"%s:[%s]:%u", schema, host, port);
409 snprintf(buf, size,
"%s:%s:%u", schema, host, port);
415 if(!Socket::query(
entry, host,
sizeof(host)))
418 if(
entry->sa_family == AF_INET6)
419 snprintf(buf, size,
"%s:[%s]:%u", schema, host, (
unsigned)ntohs(((
struct sockaddr_in6 *)(
entry))->sin6_port) & 0xffff);
422 snprintf(buf, size,
"%s:%s:%u", schema, host, (
unsigned)ntohs(((
struct sockaddr_in *)(
entry))->sin_port) & 0xffff);
Used for definitions of plugin modules.
Some convenience methods for manipulating SIP uri's.
static voip::context_t udp_context
static voip::context_t tls_context
Manipulate address strings.
static voip::context_t tcp_context
struct sockaddr_storage addr
struct sockaddr * next(void)
static LinkedObject * getGenerics(void)
struct sockaddr * find(uint16_t priority, uint32_t weight)
voip::context_t route(const char *uri, char *buf, size_t size)
Service configuration and component callbacks.
static voip::context_t out_context
static bool hostid(const char *sipuri, char *buffer, size_t size)
uint32_t total(uint16_t priority)
void set(const char *uri)
static unsigned short portid(const char *sipuri)
uint16_t after(uint16_t priority=0)