SIP Witch 1.9.15
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
thread.cpp
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #include "server.h"
18 
19 namespace sipwitch {
20 
21 static volatile bool warning_registry = false;
22 static bool shutdown_flag = false;
23 static unsigned shutdown_count = 0;
24 static unsigned startup_count = 0;
25 static unsigned active_count = 0;
26 
27 static char *remove_quotes(char *c)
28 {
29  assert(c != NULL);
30 
31  char *o = c;
32  char *d = c;
33  if(*c != '\"')
34  return c;
35 
36  ++c;
37 
38  while(*c)
39  *(d++) = *(c++);
40 
41  *(--d) = 0;
42  return o;
43 }
44 
45 thread::thread(voip::context_t ctx, const char *tag) : DetachedThread(stack::sip.stacksize)
46 {
47  to = NULL;
48  from = NULL;
49  access = NULL;
50  routed = NULL;
51  reginfo = NULL;
52  session = NULL;
53  instance = tag;
54  context = ctx;
55 }
56 
58 {
59  switch(ev) {
60 #ifndef EXOSIP_API4
61  case EXOSIP_REGISTRATION_REFRESHED:
62 #endif
64  return "register";
65  case EXOSIP_CALL_INVITE:
66  return "invite";
68  return "reinvite";
69 #ifndef EXOSIP_API4
70  case EXOSIP_CALL_TIMEOUT:
71  return "timeout";
72 #endif
76  return "noanswer";
82  return "proceed";
84  return "ring";
90  return "answer";
96  return "redirect";
97 #ifndef EXOSIP_API4
98  case EXOSIP_REGISTRATION_TERMINATED:
99 #endif
101  return "noreg";
107  return "failed";
113  return "server";
119  return "global";
120  case EXOSIP_CALL_ACK:
121  return "ack";
122  case EXOSIP_CALL_CLOSED:
124  return "bye";
126  return "cancel";
127  case EXOSIP_MESSAGE_NEW:
130  return "new";
132  return "notify";
133  default:
134  break;
135  }
136  return "unknown";
137 }
138 
139 void thread::publish(void)
140 {
141  int error = SIP_BAD_REQUEST;
142  voip::body_t mbody = NULL;
143  voip::ctype_t ct;
144  const char *tmp = NULL;
146  bool presence = false;
147  bool basic = true;
148  char msgtype[128];
149  const char *content = msgtype;
150  const char *expires = NULL;
151  const char *event = NULL;
152  voip::hdr_t msgheader;
153 
154  if(destination != LOCAL)
155  goto final;
156 
157  if(!reginfo || !reginfo->is_user())
158  goto final;
159 
160  if(!String::equal(reginfo->userid, identity))
161  goto final;
162 
163  osip_message_get_body(sevent->request, 0, &mbody);
164  ct = sevent->request->content_type;
165  if(mbody)
166  tmp = mbody->body;
167 
168  msgheader = NULL;
170  if(msgheader && msgheader->hvalue)
171  expires = msgheader->hvalue;
172 
173  msgheader = NULL;
175  if(msgheader && msgheader->hvalue)
176  event = msgheader->hvalue;
177 
178  if(ct && ct->subtype)
179  snprintf(msgtype, sizeof(msgtype), "%s/%s", ct->type, ct->subtype);
180  else if(ct && ct->type)
181  String::set(msgtype, sizeof(msgtype), ct->type);
182  else
183  content = NULL;
184 
185  // publish event to forwarders...
186  server::announce(reginfo, content, event, expires, tmp);
187 
188  // if not presence event, then skip local parsing...
189  if(event && stricmp(event, "presence")) {
190  error = SIP_OK;
191  goto final;
192  }
193 
194  while(tmp && *tmp)
195  {
196  if(!strnicmp(tmp, "<presence", 9))
197  presence = true;
198  else if(!strnicmp(tmp, "</basic", 7))
199  basic = false;
200  else if(!strnicmp(tmp, "</status>", 9))
201  break;
202  else if(!strnicmp(tmp, "<basic>open", 11) && basic) {
203  status = registry::target::READY;
204  tmp += 10;
205  }
206  else if(!strnicmp(tmp, "<show>dnd", 9) && presence) {
207  status = registry::target::DND;
208  break;
209  }
210  else if(!strnicmp(tmp, "<basic>closed", 13) && basic) {
211  status = registry::target::OFFLINE;
212  break;
213  }
214  else if(!strnicmp(tmp, "available", 9) && presence) {
215  status = registry::target::READY;
216  break;
217  }
218  else if(!strnicmp(tmp, "unavailable", 11) && presence) {
219  status = registry::target::OFFLINE;
220  break;
221  }
222  else if(!strnicmp(tmp, "on-the-phone", 12) && presence) {
223  status = registry::target::BUSY;
224  break;
225  }
226  else if(!strnicmp(tmp, "online", 6) && presence) {
227  tmp += 5;
228  status = registry::target::READY;
229  }
230  else if(!strnicmp(tmp, "busy", 4) && presence) {
231  status = registry::target::BUSY;
232  break;
233  }
234  else if(!strnicmp(tmp, "dnd", 3) && presence) {
235  status = registry::target::DND;
236  break;
237  }
238  else if(!strnicmp(tmp, "vacation", 8) && presence)
239  {
240  status = registry::target::AWAY;
241  break;
242  }
243  else if(!strnicmp(tmp, "away", 4) && presence)
244  {
245  status = registry::target::AWAY;
246  break;
247  }
248  ++tmp;
249  }
250 
251  reginfo->update(via_address, status);
252  error = SIP_OK;
253 
254 final:
255  send_reply(error);
256 }
257 
258 void thread::message(void)
259 {
260  voip::ctype_t ct;
261  voip::body_t body = NULL;
262  char address[MAX_URI_SIZE];
263  char fromhdr[MAX_URI_SIZE];
264  char target[MAX_URI_SIZE];
265  char msgtype[64];
266  char sysid[64];
267  char *msglen = NULL;
268  const char *id = NULL;
269  const char *digest = NULL;
270  const char *hash = NULL;
271 
272  switch(destination) {
273  case LOCAL:
274  if(!dialed.keys) {
276  return;
277  }
278  id = service::getValue(dialed.keys, "extension");
279  if(!id)
280  id = service::getValue(dialed.keys, "id");
281  String::set(target, sizeof(target), id);
282  break;
283  case EXTERNAL:
284  String::set(target, sizeof(target), requesting);
285  break;
286  case REDIRECTED:
287  // -digest-: get user digest into "digest" buffer
288  if(authorized.keys) {
290  if(hash)
291  digest = hash;
292  else
293  digest = server::getValue(authorized.keys, "digest");
294  }
295  if(!digest) {
297  return;
298  }
299  String::set(target, sizeof(target), requesting);
300  break;
301  default:
303  return;
304  }
305 
307  ct = sevent->request->content_type;
308  if(!body || !ct || !ct->type) {
310  digests::release(hash);
311  return;
312  }
313 
314  if(ct->subtype)
315  snprintf(msgtype, sizeof(msgtype), "%s/%s",
316  ct->type, ct->subtype);
317  else
318  snprintf(msgtype, sizeof(msgtype), "%s",
319  ct->type);
320 
321  if(extension && !digest)
322  snprintf(sysid, sizeof(sysid), "%u", extension);
323  else
324  String::set(sysid, sizeof(sysid), identity);
325 
326  uri::publish(requesting, address, sysid, sizeof(address));
327  if(extension && !display[0])
328  snprintf(fromhdr, sizeof(fromhdr),
329  "\"%u\" <%s;user=phone>", extension, address);
330  else if(display[0])
331  snprintf(fromhdr, sizeof(fromhdr),
332  "\"%s\" <%s>", display, address);
333  else
334  snprintf(fromhdr, sizeof(fromhdr),
335  "<%s>", address);
336 
337  shell::debug(3, "sending message from %s to %s\n", sysid, target);
339  if(!msglen) {
340  digests::release(hash);
342  return;
343  }
344  send_reply(messages::deliver(target, sysid, fromhdr, body->body, atoi(msglen), msgtype, digest));
345  digests::release(hash);
346  osip_free(msglen);
347 }
348 
349 void thread::invite(void)
350 {
351  const char *target = dialing;
352  voip::body_t body = NULL;
353  stack::call *call = session->parent;
354  unsigned toext = 0;
355  voip::hdr_t msgheader = NULL;
356  char fromext[32];
357  cdr *cdrnode = NULL;
358  const char *domain = registry::getDomain();
359 
360  uri::serviceid(requesting, call->request, sizeof(call->request));
361 
362  if(!domain)
363  domain = requesting;
364 
365  if(!access)
366  getsource();
367 
368  if(String::equal(network, "decline")) {
370  call->failed(this, session);
371  return;
372  }
373 
374  if(String::equal(network, "reject")) {
376  call->failed(this, session);
377  return;
378  }
379 
380  if(access && access->offline()) {
382  call->failed(this, session);
383  }
384 
385  if(extension)
386  snprintf(fromext, sizeof(fromext), "%u", extension);
387 
388  msgheader = NULL;
390  if(msgheader && msgheader->hvalue && msgheader->hvalue[0]) {
391  time(&call->expires);
392  call->expires += atol(msgheader->hvalue);
393  }
394 
395  msgheader = NULL;
396  osip_message_get_subject(sevent->request, 0, &msgheader);
397  if(msgheader && msgheader->hvalue && msgheader->hvalue[0])
398  String::set(call->subject, sizeof(call->subject), msgheader->hvalue);
399  else
400  String::set(call->subject, sizeof(call->subject), "inviting call");
401 
402  msgheader = NULL;
403  osip_message_get_expires(sevent->request, 0, &msgheader);
404  if(msgheader && msgheader->hvalue && atol(msgheader->hvalue))
405  header_expires = atol(msgheader->hvalue);
406  else
407  header_expires = 120;
408 
410  if(body && body->body)
411  String::set(session->sdp, sizeof(session->sdp), body->body);
412 
413  if(dialed.keys) {
414  target = service::getValue(dialed.keys, "extension");
415  if(target)
416  toext = atoi(target);
417  target = service::getValue(dialed.keys, "id");
418  }
419  else if(reginfo) {
420  target = reginfo->userid;
421  toext = reginfo->ext;
422  }
423 
424  time(&call->starting);
425  cdrnode = cdr::get();
426  cdrnode->type = cdr::START;
427  cdrnode->starting = call->starting;
428  cdrnode->sequence = session->sequence;
429  cdrnode->cid = session->cid;
430  String::set(cdrnode->uuid, sizeof(cdrnode->uuid), session->uuid);
431  String::set(cdrnode->network, sizeof(cdrnode->network), network);
432 
433  call->type = destination;
434  switch(destination) {
435  case LOCAL:
436  if(extension)
437  snprintf(session->sysident, sizeof(session->sysident), "%u", extension);
438  else
439  String::set(session->sysident, sizeof(session->sysident), identity);
440  if(display[0])
441  String::set(session->display, sizeof(session->display), display);
442  else
443  String::set(session->display, sizeof(session->display), session->sysident);
444 
445  String::set(call->dialed, sizeof(call->dialed), dialing);
446  String::set(cdrnode->ident, sizeof(cdrnode->ident), session->sysident);
447  String::set(cdrnode->dialed, sizeof(cdrnode->dialed), call->dialed);
448  String::set(cdrnode->display, sizeof(cdrnode->display), session->display);
449  snprintf(session->identity, sizeof(session->identity), "%s:%s@%s",
450  stack::sip.getScheme(), session->sysident, domain);
451 
452  if(toext) {
453  call->phone = true;
454  snprintf(call->dialed, sizeof(call->dialed), "%u", toext);
455  }
456  else
457  String::set(call->dialed, sizeof(call->dialed), target);
458 
459  if(reginfo && !strcmp(reginfo->userid, identity)) {
460  shell::debug(1, "calling self %08x:%u, id=%s\n",
462 
463  String::set(call->subject, sizeof(call->subject), "calling self");
464  call->busy(this);
465  cdr::post(cdrnode);
466  return;
467  }
468 
469  if(extension && !display[0])
470  snprintf(session->from, sizeof(session->from),
471  "\"%s\" <%s;user=phone>", session->sysident, session->identity);
472  else if(display[0])
473  snprintf(session->from, sizeof(session->from),
474  "\"%s\" <%s>", session->display, session->identity);
475  else
476  snprintf(session->from, sizeof(session->from),
477  "<%s>", session->identity);
478 
479  session->closed = false;
481  shell::debug(1, "local call %08x:%u for %s from %s\n",
483  break;
484  case PUBLIC:
485  String::set(call->dialed, sizeof(call->dialed), target);
486  snprintf(session->identity, sizeof(session->identity), "%s:%s@%s:%s",
488  snprintf(session->sysident, sizeof(session->sysident), "%s@%s", from->url->username, from->url->host);
489  if(from->displayname) {
490  String::set(session->display, sizeof(session->display), from->displayname);
491  snprintf(session->from, sizeof(session->from),
492  "\"%s\" <%s>", from->displayname, session->identity);
493  }
494  else {
495  String::set(session->display, sizeof(session->display), from->url->username);
496  snprintf(session->from, sizeof(session->from),
497  "<%s>", session->identity);
498  }
499  shell::debug(1, "incoming call %08x:%u for %s from %s\n",
501 
502  String::set(cdrnode->ident, sizeof(cdrnode->ident), session->sysident);
503  String::set(cdrnode->dialed, sizeof(cdrnode->dialed), call->dialed);
504  String::set(cdrnode->display, sizeof(cdrnode->display), session->display);
505  session->closed = false;
506  registry::incUse(NULL, stats::INCOMING); // external...
507  break;
508  case REDIRECTED:
509  case EXTERNAL:
510  if(extension)
511  snprintf(session->sysident, sizeof(session->sysident), "%u", extension);
512  else
513  String::set(session->sysident, sizeof(session->sysident), identity);
515  if(display[0])
516  String::set(session->display, sizeof(session->display), display);
517  else
518  String::set(session->display, sizeof(session->display), identity);
519 
521  snprintf(session->identity, sizeof(session->identity), "%s:%s@%s",
522  stack::sip.getScheme(), session->sysident, domain);
523  else {
524  gethostname(buftemp, sizeof(buftemp));
525  snprintf(session->identity, sizeof(session->identity), "%s:%s@%s",
527  }
528 
529  if(destination == EXTERNAL)
530  uri::identity(request_address.getAddr(), call->dialed, uri->username, sizeof(call->dialed));
531  else
532  String::set(call->dialed, sizeof(call->dialed), dialing);
533 
534  if(extension && !display[0])
535  snprintf(session->from, sizeof(session->from),
536  "\"%s\" <%s;user=phone>", session->sysident, session->identity);
537  else if(display[0])
538  snprintf(session->from, sizeof(session->from),
539  "\"%s\" <%s>", display, session->identity);
540  else
541  snprintf(session->from, sizeof(session->from),
542  "<%s>", session->identity);
543 
544  shell::debug(1, "outgoing call %08x:%u from %s to %s",
546 
547  String::set(cdrnode->ident, sizeof(cdrnode->ident), session->sysident);
548  String::set(cdrnode->dialed, sizeof(cdrnode->dialed), call->dialed);
549  String::set(cdrnode->display, sizeof(cdrnode->display), session->display);
550  if(destination == REDIRECTED)
552  else
554 
555  session->closed = false;
556  goto exit;
557  case ROUTED:
558  call->phone = true;
559 
560  if(extension)
561  snprintf(session->sysident, sizeof(session->sysident), "%u", extension);
562  else
563  String::set(session->sysident, sizeof(session->sysident), identity);
564  if(display[0])
565  String::set(session->display, sizeof(session->display), display);
566  else
567  String::set(session->display, sizeof(session->display), session->sysident);
568 
569  snprintf(session->identity, sizeof(session->identity), "%s:%s@%s",
570  stack::sip.getScheme(), session->sysident, domain);
571 
572  if(extension)
573  snprintf(session->from, sizeof(session->from),
574  "\"%s\" <%s;user=phone>", session->display, session->identity);
575  else
576  snprintf(session->from, sizeof(session->from),
577  "\"%s\" <%s>", session->display, session->identity);
578 
579  String::set(call->dialed, sizeof(call->dialed), dialing);
580 
581  String::set(cdrnode->ident, sizeof(cdrnode->ident), session->sysident);
582  String::set(cdrnode->dialed, sizeof(cdrnode->dialed), call->dialed);
583  String::set(cdrnode->display, sizeof(cdrnode->display), session->display);
584  session->closed = false;
586  shell::debug(1, "dialed call %08x:%u for %s from %s, dialing=%s\n",
587  session->sequence, session->cid, target, getIdent(), dialing);
588  break;
589  default:
590  String::set(cdrnode->ident, sizeof(cdrnode->ident), "unknown");
591  String::set(cdrnode->dialed, sizeof(cdrnode->dialed), dialing);
592  String::set(cdrnode->display, sizeof(cdrnode->display), "");
593  session->closed = true;
594  break;
595  }
596 
597  call->map->sequence = session->sequence;
598  call->map->cid = session->cid;
599  String::set(call->map->source, sizeof(call->map->source), session->sysident);
600  String::set(call->map->display, sizeof(call->map->display), session->display);
601  if(reginfo) {
602  // get rid of config ref if we are calling registry target
604 
605  String::set(call->forward, MAX_USERID_SIZE, reginfo->userid);
606  call->forwarding = "na";
608  }
609 
610  if(dialed.keys) {
611  // PROCESS DIALED HERE IF EXISTS...
612  }
613 
614 exit:
615  if(cdrnode)
616  cdr::post(cdrnode);
617 
618  if(!call->invited && !stack::forward(call)) {
619  call->busy(this);
620  return;
621  }
622 
623  call->trying(this);
624  shell::debug(2, "call proceeding %08x:%u\n", session->sequence, session->cid);
625  return;
626 
627 // noproxy:
628 // send_reply(SIP_SERVICE_UNAVAILABLE);
629 // call->failed(this, session);
630 }
631 
633 {
634  registry::mapped *rr = NULL;
635 
636  if(!stack::sip.trusted || !getsource() || !access)
637  return;
638 
639  if(!String::ifind(stack::sip.trusted, access->getName(), ",; \t\n"))
640  return;
641 
642  // trust also only if no intermediary proxies
643  if(via_hops == 1)
644  rr = registry::address(via_address.getAddr());
645  if(!rr)
646  return;
647 
648  String::set(display, sizeof(display), rr->display);
649  extension = rr->ext;
650  String::set(identity, sizeof(identity), rr->userid);
652  registry::detach(rr);
653 }
654 
655 const char *thread::getIdent(void)
656 {
657  if(!extension)
658  return identity;
659 
660  if(registry::isExtension(identity) && (unsigned)atoi(identity) == extension)
661  return identity;
662 
663  if(!identbuf[0])
664  snprintf(identbuf, sizeof(identbuf), "%s(%u)", identity, extension);
665 
666  return identbuf;
667 }
668 
670 {
671  registry::mapped *rr = NULL;
672 
673  if(!stack::sip.trusted || !getsource() || !access)
674  goto untrusted;
675 
676  if(!String::ifind(stack::sip.trusted, access->getName(), ",; \t\n"))
677  goto untrusted;
678 
679  rr = registry::address(via_address.getAddr());
680  if(!rr)
681  goto untrusted;
682 
683  extension = rr->ext;
684  String::set(display, sizeof(display), rr->display);
685  String::set(identity, sizeof(identity), rr->userid);
687  registry::detach(rr);
688  if(authorized.keys)
689  return true;
690 
691 untrusted:
692  if(via_host)
693  shell::debug(2, "challenge required for %s:%u", via_host, via_port);
694  else
695  shell::debug(2, "%s", "challenge request required");
696  challenge();
697  return false;
698 }
699 
701 {
702  int error = SIP_UNDECIPHERABLE;
703  const char *scheme = "sip";
704  const char *cp;
705  time_t now;
706  unsigned level;
707  profile_t *pro;
708  const char *target = NULL;
709  char dbuf[MAX_USERID_SIZE];
710  registry::pattern *pp;
711 // unsigned to_port = stack::sip_port;
712  unsigned local_port = stack::sip_port;
713  const char *sep1 = "", *sep2 = "";
714  const char *refer = NULL;
715  const char *uri_host;
716  struct sockaddr_internet iface;
717  voip::hdr_t msgheader = NULL;
718  bool anon = false;
719  UserCache *usercache = NULL;
720  bool allowed = false;
721 
723  goto invalid;
724 
725  from_port = 5060;
726  from = sevent->request->from;
728  to = sevent->request->to;
729  uri_host = uri->host;
730 
732  if(msgheader && msgheader->hvalue)
733  if(!stricmp(msgheader->hvalue, "no") || !strnicmp(msgheader->hvalue, "anon", 4))
734  anon = true;
735 
736  error = SIP_ADDRESS_INCOMPLETE;
737 
738  if(context == stack::sip.tls_context)
739  scheme = "sips";
740 
741  if(!uri_host && registry::getDomain())
742  uri_host = (char *)registry::getDomain();
743 
744  if(!from->url->host || !uri_host)
745  goto invalid;
746 
747  if(!from->url->username || !uri->username)
748  goto invalid;
749 
750  if(!from->url->scheme || !uri->scheme)
751  goto invalid;
752 
754  if(stricmp(from->url->scheme, scheme) || stricmp(uri->scheme, scheme))
755  goto invalid;
756 
757  if(strchr(uri_host, ':') != NULL && uri_host[0] != '[') {
758  sep1 = "[";
759  sep2 = "]";
760  }
761 
762  if(uri->username && uri->username[0]) {
763  if(uri->port && uri->port[0])
764  snprintf(requesting, sizeof(requesting), "%s:%s@%s%s%s:%s",
765  uri->scheme, uri->username, sep1, uri_host, sep2, uri->port);
766  else
767  snprintf(requesting, sizeof(requesting), "%s:%s@%s%s%s",
768  uri->scheme, uri->username, sep1, uri_host, sep2);
769  }
770  else {
771  if(uri->port && uri->port[0])
772  snprintf(requesting, sizeof(requesting), "%s:%s%s%s:%s",
773  uri->scheme, sep1, uri_host, sep2, uri->port);
774  else
775  snprintf(requesting, sizeof(requesting), "%s:%s%s%s",
776  uri->scheme, sep1, uri_host, sep2);
777  }
778 
779  if(uri->port && uri->port[0])
780  local_port = atoi(uri->port);
781  if(from->url->port)
782  from_port = atoi(from->url->port);
783 // if(to->url->port && to->url->port[0])
784 // to_port = atoi(to->url->port);
785  if(!local_port)
786  local_port = 5060;
787  if(!from_port)
788  from_port = 5060;
789 // if(!to_port)
790 // to_port = 5060;
791 
792 /* shell::debug(3, "request from=%s:%s@%s:%d, uri=%s:%s@%s:%d, to=%s:%s@%s:%d\n",
793  from->url->scheme, from->url->username, from->url->host, from_port,
794  uri->scheme, uri->username, uri_host, local_port,
795  to->url->scheme, to->url->username, to->url->host, to_port);
796 */
797 
798  // if marked as a remote call, we can skip local tests entirely
799  if(anon)
800  goto remote;
801 
802  // bypass request address processing if local domain call....
803  memset(&iface, 0, sizeof(iface));
804 
805  if(eq(registry::getRealm(), uri_host))
806  goto local;
807 
808  if(eq("localdomain", uri_host))
809  goto local;
810 
811  if(String::ifind(stack::sip.localnames, uri_host, " ,;:\t\n"))
812  goto local;
813 
814  if(stack::sip_contact && eq((const char *)stack::sip_contact, uri_host))
815  goto local;
816 
817  if(stack::sip_publish && eq((const char *)stack::sip_publish, uri_host))
818  goto local;
819 
820  request_address.set(uri_host, local_port);
821 
822  if(request_address.getAddr() == NULL) {
823  shell::log(shell::ERR, "unresolvable request: %s", uri_host);
824  error = SIP_ADDRESS_INCOMPLETE;
825  goto invalid;
826  }
827 
828  stack::getInterface((struct sockaddr *)&iface, request_address.getAddr());
829 
830  if(local_port != stack::sip_port)
831  goto remote;
832 
833  if(eq_host((struct sockaddr *)&iface, request_address.getAddr()))
834  goto local;
835 
836  goto remote;
837 
838 local:
839  shell::debug(2, "authorizing local; target=%s\n", uri->username);
840  target = uri->username;
841  destination = LOCAL;
842  String::set(dialing, sizeof(dialing), target);
843 
844 rewrite:
845  shell::debug(3, "rewrite process; target=%s, dialing=%s\n", target, dialing);
846  error = SIP_NOT_FOUND;
847  if(!target || !*target || strlen(target) >= MAX_USERID_SIZE)
848  goto invalid;
849 
850  // handle anon@here and system@here identities...
851 
852  if(!stricmp(target, stack::sip.anon))
853  goto invalid;
854 
855  if(!stricmp(target, stack::sip.system)) {
856  error = SIP_FORBIDDEN;
857  goto invalid;
858  }
859 
860  reginfo = registry::dialing(target);
861  server::getDialing(target, dialed);
862 
863  shell::debug(4, "rewrite process; registry=%p, dialed=%p\n", (void *)reginfo, (void *)dialed.keys);
864 
865  if(!reginfo && !dialed.keys)
866  goto routing;
867 
868  // reject nodes with defined errors
869  if(dialed.keys && !stricmp(dialed.keys->getId(), "reject")) {
870  cp = service::getValue(dialed.keys, "error");
871  if(cp)
872  error = atoi(cp);
873  goto invalid;
874  }
875 
876  if(!reginfo && dialed.keys) {
877  if(!stricmp(dialed.keys->getId(), "group"))
878  return authenticate();
879  if(!stricmp(dialed.keys->getId(), "refer"))
880  return authenticate();
881  if(!stricmp(dialed.keys->getId(), "test")) {
882  if(session && authenticate()) {
884  cp = service::getValue(dialed.keys, "error");
885  if(cp) {
886  error = atoi(cp);
887  goto invalid;
888  }
889  return true;
890  }
891  return false;
892  }
893  if(!stricmp(dialed.keys->getId(), "queue"))
894  goto anonymous;
895  if(!stricmp(dialed.keys->getId(), "user") || !stricmp(dialed.keys->getId(), "admin")) {
897  goto trying;
898  shell::log(shell::NOTIFY, "unregistered destination %s", target);
899  }
900  else
901  shell::log(shell::ERR, "invalid destination %s, type=%s\n", target, dialed.keys->getId());
902  error = SIP_GONE;
903  goto invalid;
904  }
905 
908  goto trying;
909  error = SIP_GONE;
910  goto invalid;
911  }
912 
913  time(&now);
914 
915  if(reginfo && reginfo->expires && reginfo->expires < now) {
916  if(!MSG_IS_MESSAGE(sevent->request)) {
917  error = SIP_GONE;
918  goto invalid;
919  }
920  }
921  else if(reginfo && !dialed.keys) {
922  error = SIP_NOT_FOUND;
923  goto invalid;
924  }
925 
926 trying:
927  // should SIP_GONE expiration and other checks be here??
928 
930  return authenticate();
931 
932  // extension references always require authentication
933  if(registry::isExtension(target)) {
934  if(!authenticate())
935  return false;
937  goto invalid;
938  return true;
939  }
940 
941  // see if destination allows anonymous remote (public) callers.
942  // destination must be valid and either have class of service
943  // or server is in hotspot mode. Origin must offer a host uri.
944 
945  allowed = false;
946  if(reginfo && from && from->url && from->url->host) {
948  allowed = true;
949  else
951  }
952 
953  if(allowed) {
954 
955  // now we make sure the originating call does not "claim" to be
956  // associated with us. If it has any of our our names, then we have
957  // the inbound caller authenticate like any local-to-local call
958 
959  if(String::equal(registry::getRealm(), from->url->host))
960  return authenticate();
961 
962  if(String::equal("localdomain", from->url->host))
963  return authenticate();
964 
965  if(stack::sip_contact && eq((const char *)stack::sip_contact, uri_host))
966  return authenticate();
967 
968  if(stack::sip_publish && eq((const char *)stack::sip_publish, uri_host))
969  return authenticate();
970 
971  if(String::ifind(stack::sip.localnames, from->url->host, " ,;:\t\n"))
972  return authenticate();
973 
974  // It "seems" external, user allows incoming, handle as public
975  goto anonymous;
976  }
977 
978  return authenticate();
979 
980 routing:
981  // cannot re-route extension #s...
982  if(registry::isExtension(target))
983  goto invalid;
984 
986  if(!authenticate() || !authorized.keys)
987  return false;
988 
989  if(!stricmp(authorized.keys->getId(), "user")) {
990  cp = service::getValue(authorized.keys, "profile");
991  if(!cp)
992  cp = "*";
993  pro = server::getProfile(cp);
994  level = pro->level;
995  }
996  else
997  level = registry::getRoutes();
998  cp = service::getValue(authorized.keys, "trs");
999  if(cp)
1000  level = atoi(cp);
1001 
1002  if(!level)
1003  goto invalid;
1004 
1005  pp = registry::getRouting(level, target);
1006  if(!pp)
1007  goto static_routing;
1008 
1009  reginfo = pp->registry;
1010  dialing[0] = 0;
1011  if(pp->prefix[0] == '-') {
1012  if(!strnicmp(target, pp->prefix + 1, strlen(pp->prefix) - 1))
1013  target += strlen(pp->prefix) - 1;
1014  } else if(pp->prefix[0]) {
1015  if(strnicmp(target, pp->prefix, strlen(pp->prefix)))
1016  String::set(dialing, sizeof(dialing), pp->prefix);
1017  }
1018  String::add(dialing, sizeof(dialing), target);
1019  if(pp->suffix[0] == '-') {
1020  if(strlen(dialing) > strlen(pp->suffix) && !stricmp(dialing + strlen(dialing) - strlen(pp->suffix) + 1, pp->suffix + 1))
1021  dialing[strlen(dialing) - strlen(pp->suffix) + 1] = 0;
1022  } else
1023  String::add(dialing, sizeof(dialing), pp->suffix);
1024  return true;
1025 
1026 static_routing:
1027  routed = server::getRouting(target);
1028  if(!routed) {
1030  refer = server::referLocal(idmap, target, buffer, sizeof(buffer));
1031  registry::detach(idmap);
1032  if(refer)
1033  goto redirect;
1034  }
1035 
1036  if(!routed)
1037  usercache = UserCache::find(target);
1038 
1039  if(usercache) {
1040  stack::sipAddress(&usercache->address, buffer, target, sizeof(buffer));
1041  refer = buffer;
1042  UserCache::release(usercache);
1043  goto redirect;
1044  }
1045 
1046  if(!routed)
1047  goto invalid;
1048 
1049  if(!stricmp(routed->getId(), "refuse")) {
1050  cp = service::getValue(routed, "error");
1051  if(cp)
1052  error = atoi(cp);
1053  goto invalid;
1054  }
1055 
1056  if(!stricmp(routed->getId(), "redirect") || !stricmp(routed->getId(), "refer")) {
1057  cp = service::getValue(routed, "server");
1058  if(!cp)
1059  cp = service::getValue(routed, "target");
1060  if(cp && !strchr(cp, '@')) {
1061  if(String::equal(cp, "sip:", 4) || String::equal(cp, "sips:", 5))
1062  snprintf(buffer, sizeof(buffer), "%s@%s", target, cp);
1063  else
1064  snprintf(buffer, sizeof(buffer), "sip:%s@%s", target, cp);
1065  refer = buffer;
1066  goto redirect;
1067  }
1068  if(!cp)
1069  goto invalid;
1070  if(String::equal(cp, "sip:", 4) || String::equal(cp, "sips:"))
1071  snprintf(buffer, sizeof(buffer), "%s", cp);
1072  else
1073  snprintf(buffer, sizeof(buffer), "sip:%s", cp);
1074  refer = buffer;
1075  goto redirect;
1076  }
1077 
1078  // adjust dialing & processing based on routing properties
1079 
1080  cp = service::getValue(routed, "replace");
1081  if(cp)
1082  String::set(dialing, sizeof(dialing), cp);
1083  else {
1084  dialing[0] = 0;
1085  cp = service::getValue(routed, "prefix");
1086  if(cp && *cp == '-') {
1087  --cp;
1088  if(!strnicmp(target, cp, strlen(cp)))
1089  target += strlen(cp);
1090  } else if(cp) {
1091  if(strnicmp(target, cp, strlen(cp)))
1092  String::set(dialing, sizeof(dialing), cp);
1093  }
1094  String::add(dialing, sizeof(dialing), target);
1095  cp = service::getValue(routed, "suffix");
1096  if(cp && *cp == '-') {
1097  --cp;
1098  if(strlen(dialing) >= strlen(cp) && !stricmp(dialing + strlen(dialing) - strlen(cp), cp))
1099  dialing[strlen(dialing) - strlen(cp)] = 0;
1100  } else if(cp)
1101  String::add(dialing, sizeof(dialing), cp);
1102  }
1103  if(!stricmp(routed->getId(), "rewrite")) {
1104  if(strchr(dialing, '@')) {
1105  if(String::equal(dialing, "sips:", 5) || String::equal("sip:", dialing, 4))
1106  snprintf(dbuf, sizeof(dbuf), "%s", dialing);
1107  else
1108  snprintf(dbuf, sizeof(dbuf), "sip:%s", dialing);
1109  refer = dbuf;
1110  goto redirect;
1111  }
1112  String::set(dbuf, sizeof(dbuf), dialing);
1113  target = dbuf;
1115  if(reginfo)
1117  routed = NULL;
1118  reginfo = NULL;
1119  destination = LOCAL;
1120  goto rewrite;
1121  }
1122  goto invalid;
1123 
1124 anonymous:
1125  if(!stack::sip.published && !stack::sip_public) {
1126  error = SIP_FORBIDDEN;
1127  goto invalid;
1128  }
1129 
1130  if(from->url->host == NULL) {
1131  error = SIP_ADDRESS_INCOMPLETE;
1132  goto invalid;
1133  }
1134 
1135  destination = PUBLIC;
1136  return true;
1137 
1138 remote:
1139  error = SIP_FORBIDDEN;
1141  if(!stack::sip.published && !stack::sip_public)
1142  goto invalid;
1143 
1144  if(!authenticate())
1145  return false;
1146 
1147  // must be active registration with correct class of service, or with
1148  // server in hotspot mode, to dial out...
1150  time(&now);
1151  if(!reginfo || (reginfo->expires && reginfo->expires < now))
1152  goto invalid;
1153 
1154  if(!stack::sip_public)
1156  goto invalid;
1157 
1158  refer = server::referRemote(reginfo, requesting, buffer, sizeof(buffer));
1159  if(refer)
1160  goto redirect;
1161 
1162  return true;
1163 
1164 invalid:
1165  if(authorized.keys)
1166  shell::debug(1, "rejecting invite from %s; error=%d\n", getIdent(), error);
1167  else if(from->url && from->url->host && from->url->username)
1168  shell::debug(1, "rejecting invite from %s@%s; error=%d\n", from->url->username, from->url->host, error);
1169  else
1170  shell::debug(1, "rejecting unknown invite; error=%d\n", error);
1171 
1172  send_reply(error);
1173  return false;
1174 
1175 redirect:
1177  String::set(requesting, sizeof(requesting), refer);
1178  return true;
1179 }
1180 
1181 void thread::send_reply(int error)
1182 {
1183  assert(error >= 100);
1184 
1185  voip::msg_t reply = NULL;
1186 
1187  switch(authorizing) {
1188  case CALL:
1189  if(voip::make_answer_response(context, sevent->tid, error, &reply)) {
1190  if(context == stack::sip.udp_context)
1191  voip::server_requires(reply, "100rel");
1192  stack::siplog(reply);
1193  voip::send_answer_response(context, sevent->tid, error, reply);
1194  }
1195  else
1197  break;
1198  case REGISTRAR:
1199  case MESSAGE:
1200  if(voip::make_response_message(context, sevent->tid, error, &reply)) {
1201  if(context == stack::sip.udp_context)
1202  voip::server_requires(reply, "100rel");
1203  stack::siplog(reply);
1204  voip::send_response_message(context, sevent->tid, error, reply);
1205  }
1206  else
1208 break;
1209  default:
1210  break;
1211  }
1212 }
1213 
1215 {
1216  assert(s != NULL);
1217 
1218  const char *userid = NULL, *secret = NULL;
1219  registry::mapped *rr = s->reg;
1220  service::keynode *auth;
1221 
1222  // if not managed destination, try plugins using realm only...
1223  if(!rr)
1224  return server::authenticate(-1, sip_realm);
1225 
1226  // if has externally managed registration, call plugins to authenticate...
1227  if(rr->rid != -1)
1228  return server::authenticate(rr->rid, sip_realm);
1229 
1231  if(!authorized.keys)
1232  return false;
1233 
1234  auth = authorized.keys->leaf("authorize");
1235  if(auth) {
1236  userid = server::getValue(auth, "userid");
1237  secret = server::getValue(auth, "secret");
1238  }
1239 
1240  switch(rr->type) {
1241  // Services use special magic to authenticate using uuid generated
1242  // userid that service originally registered with as "contact". This
1243  // means that a single secret is needed for authenticating both ways
1244  // and all references to the service is instance unique.
1246  // sipwitch aware app servers can generate uuid's and use same secret
1247  if(!userid)
1248  userid = rr->remote;
1249  if(!secret)
1250  secret = service::getValue(authorized.keys, "secret");
1251  break;
1252  default:
1253  return false;
1254  }
1255 
1256  if(!sip_realm || !*sip_realm || !userid || !secret || !*userid)
1257  return false;
1258 
1259  voip::add_authentication(context, userid, secret, sip_realm, true);
1260  return true;
1261 }
1262 
1264 {
1265  voip::auth_t auth = NULL;
1266  service::keynode *node = NULL, *leaf;
1267  stringbuf<64> digest;
1269  const char *cp;
1270  const char *hash = NULL;
1271  digest_t calc(registry::getDigest());
1272 
1273  if(authorized.keys != NULL)
1274  return true;
1275 
1276  display[0] = 0;
1277  extension = 0;
1278  auth = NULL;
1279 
1280  if(!sevent->request || osip_message_get_authorization(sevent->request, 0, &auth) != 0 || !auth || !auth->username || !auth->response)
1281  return unauthenticated();
1282 
1283  remove_quotes(auth->username);
1284  remove_quotes(auth->uri);
1285  remove_quotes(auth->nonce);
1286  remove_quotes(auth->response);
1287 
1288  // if subnet restrictions and authenticated from outside, reject
1289 
1290  if(stack::sip.restricted) {
1291  if(!getsource() || !access || !String::ifind(stack::sip.restricted, access->getName(), ",; \t\n")) {
1292  if(access && via_host && !String::ifind(stack::sip.restricted, access->getName(), ",; \t\n"))
1293  shell::log(shell::NOTIFY, "restricted %s from <%s> for %s:%u",
1294  access->getName(), stack::sip.restricted, via_host, via_port);
1295  else if(via_host)
1296  shell::log(shell::NOTIFY, "rejecting restricted %s from %s:%u", auth->username, via_host, via_port);
1297  else
1298  shell::log(shell::NOTIFY, "rejecting restricted %s", auth->username);
1299  error = SIP_FORBIDDEN;
1300  goto failed;
1301  }
1302  }
1303 
1305  node = authorized.keys;
1306  if(!node) {
1307  shell::log(shell::NOTIFY, "rejecting unknown %s", auth->username);
1308  error = SIP_NOT_FOUND;
1309  goto failed;
1310  }
1311 
1312  // reject can be used as a placeholder when manually editing
1313  // provisioning records for a user that is being disabled but which
1314  // one doesn't want to loose configuration info
1315 
1316  if(!stricmp(node->getId(), "reject")) {
1317  shell::log(shell::NOTIFY, "rejecting user %s", auth->username);
1318  error = SIP_FORBIDDEN;
1319  cp = service::getValue(node, "error");
1320  if(cp)
1321  error = atoi(cp);
1322  goto failed;
1323  }
1324 
1325  leaf = node->leaf("extension");
1326  if(leaf && leaf->getPointer())
1327  extension = atoi(leaf->getPointer());
1328 
1329  leaf = node->leaf("display");
1330  if(leaf && leaf->getPointer())
1331  String::set(display, sizeof(display), leaf->getPointer());
1332 
1333  // -digest-: fetch from leaf node...
1334  hash = digests::get(auth->username);
1335  leaf = node->leaf("digest");
1336  if(!hash && (!leaf || !leaf->getPointer())) {
1337  shell::log(shell::NOTIFY, "rejecting unsupported %s", auth->username);
1338  error = SIP_FORBIDDEN;
1339  goto failed;
1340  }
1341 
1342  // compute service request digest string
1343  snprintf(buffer, sizeof(buffer), "%s:%s", sevent->request->sip_method, auth->uri);
1344 
1345  calc.puts(buffer);
1346  digest = *calc;
1347 
1348  // apply user digest pointer with nonce, and service digest string
1349  if(hash)
1350  snprintf(buffer, sizeof(buffer), "%s:%s:%s", hash, auth->nonce, *digest);
1351  else
1352  snprintf(buffer, sizeof(buffer), "%s:%s:%s", leaf->getPointer(), auth->nonce, *digest);
1353  digests::release(hash);
1354 
1355  calc.reset();
1356  calc.puts(buffer);
1357  digest = *calc;
1358 
1359  // see if digests match
1360  if(stricmp(*digest, auth->response)) {
1361  shell::log(shell::NOTIFY, "rejecting unauthorized %s", auth->username);
1362  goto failed;
1363  }
1364 
1365  String::set(identity, sizeof(identity), auth->username);
1366  return true;
1367 
1368 failed:
1370  send_reply(error);
1371  return false;
1372 }
1373 
1375 {
1376  voip::msg_t reply = NULL;
1377  char nonce[32];
1378  time_t now;
1379 
1380  time(&now);
1381  snprintf(nonce, sizeof(nonce), "%08lx", (long)now);
1382  snprintf(buffer, sizeof(buffer),
1383  "Digest realm=\"%s\", nonce=\"%s\", algorithm=%s",
1385 
1386  switch(authorizing) {
1387  case REGISTRAR:
1388  case MESSAGE:
1391  voip::server_allows(reply);
1392  stack::siplog(reply);
1394  }
1395  break;
1396  case CALL:
1399  voip::server_allows(reply);
1400  stack::siplog(reply);
1402  }
1403  break;
1404  case NONE:
1405  break;
1406  }
1407 }
1408 
1410 {
1412  int vpos = 0;
1413 
1414  if(via_address.isValid())
1415  return true;
1416 
1417  via_host = NULL;
1418  via_port = 5060;
1419  via_header = NULL;
1420  while(sevent->request && osip_list_eol(OSIP2_LIST_PTR sevent->request->vias, vpos) == 0) {
1421  via_header = (voip::via_t)osip_list_get(OSIP2_LIST_PTR sevent->request->vias, vpos++);
1422  ++via_hops;
1423  }
1424 
1425  if(!via_header)
1426  return false;
1427 
1429  if(via_header->port)
1430  via_port = atoi(via_header->port);
1431  if(!via_port)
1432  via_port = 5060;
1433 
1434  osip_via_param_get_byname(via_header, (char *)"rport", &param);
1435  if(param != NULL && param->gvalue != NULL)
1436  via_port = atoi(param->gvalue);
1437 
1438  osip_via_param_get_byname(via_header, (char *)"received", &param);
1439  if(param != NULL && param->gvalue != NULL)
1440  via_host = param->gvalue;
1441 
1443  access = server::getPolicy(via_address.getAddr());
1444  if(access) {
1445  peering = access->iface;
1446  String::set(network, sizeof(network), access->getId());
1447  }
1448  else {
1450  String::set(network, sizeof(network), "*");
1451  }
1452  if(session) {
1453  session->peering = peering;
1454  String::set(session->network, sizeof(session->network), network);
1455  }
1456  return true;
1457 }
1458 
1460 {
1461  voip::auth_t auth = NULL;
1462  service::keynode *node = NULL, *leaf;
1463  stringbuf<64> digest;
1465  const char *cp;
1466  char temp[64];
1467  voip::msg_t reply = NULL;
1468  service::usernode user;
1469  const char *hash = NULL;
1470  digest_t calc(registry::getDigest());
1471 
1472  if(!sevent->request || osip_message_get_authorization(sevent->request, 0, &auth) != 0 || !auth || !auth->username || !auth->response) {
1473  challenge();
1474  return;
1475  }
1476 
1477  remove_quotes(auth->username);
1478  remove_quotes(auth->uri);
1479  remove_quotes(auth->nonce);
1480  remove_quotes(auth->response);
1481 
1482  server::getProvision(auth->username, user);
1483  node = user.keys;
1484  if(!node) {
1485  error = SIP_NOT_FOUND;
1486  goto reply;
1487  }
1488 
1489  // reject can be used as a placeholder when manually editing
1490  // provisioning records for a user that is being disabled but which
1491  // one doesn't want to loose configuration info
1492 
1493  if(!stricmp(node->getId(), "reject")) {
1494  error = SIP_FORBIDDEN;
1495  cp = service::getValue(node, "error");
1496  if(cp)
1497  error = atoi(cp);
1498  goto reply;
1499  }
1500 
1501  // -digest-: get a leaf pointer
1502  hash = digests::get(auth->username);
1503  leaf = node->leaf("digest");
1504  if(!hash && (!leaf || !leaf->getPointer())) {
1505  error = SIP_FORBIDDEN;
1506  goto reply;
1507  }
1508 
1509  // compute a method/uri hash
1510  snprintf(buffer, sizeof(buffer), "%s:%s", sevent->request->sip_method, auth->uri);
1511  calc.puts(buffer);
1512  digest = *calc;
1513 
1514  // compute with user digest
1515  if(hash)
1516  snprintf(buffer, sizeof(buffer), "%s:%s:%s", hash, auth->nonce, *digest);
1517  else
1518  snprintf(buffer, sizeof(buffer), "%s:%s:%s", leaf->getPointer(), auth->nonce, *digest);
1519 
1520  digests::release(hash);
1521 
1522  calc.reset();
1523  calc.puts(buffer);
1524  digest = *calc;
1525 
1526  if(!stricmp(*digest, auth->response))
1527  error = SIP_OK;
1528 
1529 reply:
1530  if(error == SIP_OK)
1531  shell::debug(2, "validating %s; expires=%lu", auth->username, (long)registry::getExpires());
1532  else
1533  shell::debug(2, "rejecting %s; error=%d", auth->username, error);
1534 
1535  server::release(user);
1536  if(voip::make_response_message(context, sevent->tid, error, &reply)) {
1537  if(error == SIP_OK) {
1538  snprintf(temp, sizeof(temp), ";expires=%lu", (long)registry::getExpires());
1539  osip_message_set_contact(reply, temp);
1540  snprintf(temp, sizeof(temp), "%lu", (long)registry::getExpires());
1541  osip_message_set_expires(reply, temp);
1542  }
1543  voip::server_allows(reply);
1544  stack::siplog(reply);
1545  voip::send_response_message(context, sevent->tid, error, reply);
1546  }
1547  else
1549 }
1550 
1552 {
1553  voip::contact_t contact = NULL;
1554  voip::uri_param_t param = NULL;
1555  voip::uri_t reguri = NULL;
1556  char *port;
1557  int interval = -1;
1558  int pos = 0;
1559  int error = SIP_ADDRESS_INCOMPLETE;
1560  voip::msg_t reply = NULL;
1561  struct sockaddr_internet iface;
1562 
1563  while(osip_list_eol(OSIP2_LIST_PTR sevent->request->contacts, pos) == 0) {
1564  contact = (voip::contact_t)osip_list_get(OSIP2_LIST_PTR sevent->request->contacts, pos++);
1565  if(contact && contact->url) {
1566  osip_contact_param_get_byname(contact, (char *)"expires", &param);
1567  if(param && param->gvalue)
1568  interval = osip_atoi(param->gvalue);
1569  break;
1570  }
1571  }
1572 
1573  if(registry::getDomain())
1574  String::set(binding, sizeof(binding), registry::getDomain());
1575  else if(sevent->request->req_uri->port && !eq(sevent->request->req_uri->port, "5060"))
1576  snprintf(binding, sizeof(binding), "%s:%s",
1578  else
1579  String::set(binding, sizeof(binding), sevent->request->req_uri->host);
1580 
1581  if(contact && contact->url && contact->url->username && contact->url->username[0]) {
1582  if(!authenticate())
1583  return;
1584 
1585  if(!getsource()) {
1586  shell::log(shell::ERR, "cannot determine origin for registration");
1587  return;
1588  }
1589 
1590  reguri = contact->url;
1591  port = reguri->port;
1592  if(!port || !port[0])
1593  port = (char *)"5060";
1594  snprintf(buffer, sizeof(buffer), "%s:%s@%s:%s",
1595  reguri->scheme, reguri->username, reguri->host, port);
1596 
1597  // auto-detect registration from ephemerial ports...
1598  contact_port = atoi(port);
1599  contact_host = reguri->host;
1600  if(!Socket::is_numeric(reguri->host) || !String::equal(contact_host, via_host) || contact_port == via_port) {
1601  // non-ephemeral or source based registration required...
1604  }
1606  }
1607  else
1608  {
1609  if(stack::sip.restricted) {
1610  if(!getsource() || !access || !String::ifind(stack::sip.restricted, access->getName(), ",; \t\n")) {
1611  error = SIP_FORBIDDEN;
1612  goto reply;
1613  }
1614  }
1615 
1616  if(sevent->request->to)
1617  reguri = sevent->request->to->url;
1618  if(!uri || !reguri->username || reguri->username[0] == 0) {
1619  validate();
1620  return;
1621  }
1622 
1623  port = reguri->port;
1624  if(!port || !port[0])
1625  port = (char *)"5060";
1626  request_address.set(reguri->host, port);
1627  if(request_address.getAddr() == NULL)
1628  goto reply;
1629 
1630  error = SIP_NOT_FOUND;
1631 // if(!String::ifind(stack::sip.localnames, reguri->host, " ,;:\t\n")) {
1632  stack::getInterface((struct sockaddr *)&iface, request_address.getAddr());
1633  if(!eq_host((struct sockaddr *)&iface, request_address.getAddr()) && atoi(port) == stack::sip_port)
1634  goto reply;
1635 // }
1636 
1637  if(registry::exists(reguri->username))
1638  error = SIP_OK;
1639 
1640 reply:
1641  if(error == SIP_OK)
1642  shell::debug(3, "querying %s", reguri->username);
1643  else
1644  shell::debug(3, "query rejected for %s; error=%d", reguri->username, error);
1645  if(voip::make_response_message(context, sevent->tid, error, &reply)) {
1646  if(error == SIP_OK) {
1647  snprintf(buftemp, sizeof(buftemp), "<%s:%s@%s>",
1648  stack::getScheme(), reguri->username, binding);
1650  }
1651  voip::server_allows(reply);
1652  stack::siplog(reply);
1653  voip::send_response_message(context, sevent->tid, error, reply);
1654  }
1655  else
1657  return;
1658  }
1659 
1660  if(interval < 0)
1661  interval = header_expires;
1662  if(interval < 0)
1663  interval = (int)registry::getExpires();
1664  if(!interval || !contact) {
1665  deregister();
1666  return;
1667  }
1668  reregister(buffer, interval);
1669 }
1670 
1671 void thread::reregister(const char *contact, time_t interval)
1672 {
1673  assert(contact != NULL && *contact != 0);
1674  assert(interval > 0);
1675  assert(identity != NULL && *identity != 0);
1676 
1677  int answer = SIP_OK;
1678  voip::msg_t reply = NULL;
1679  time_t expire;
1680  unsigned count = 0;
1681  voip::contact_t c = NULL;
1682  int pos = 0;
1683  bool refresh;
1684 
1686  shell::debug(2, "rejecting %s, not in local dialing plan", getIdent());
1687  answer = SIP_NOT_ACCEPTABLE_HERE;
1688  interval = 0;
1689  goto reply;
1690  }
1691 
1693  if(!reginfo) {
1694  if(!warning_registry) {
1695  warning_registry = true;
1696  shell::log(shell::ERR, "registry capacity reached");
1697  }
1698  answer = SIP_TEMPORARILY_UNAVAILABLE;
1699  interval = 0;
1700  goto reply;
1701  }
1702  warning_registry = false;
1703  time(&expire);
1704  if(reginfo->expires < expire) {
1705  reginfo->created = expire;
1706  getDevice(reginfo);
1707  }
1708 
1709  expire += interval + 3; // overdraft 3 seconds...
1710 
1711  refresh = reginfo->refresh(contact_address, expire, contact);
1712  if(!refresh) {
1714  count = reginfo->addTarget(contact_address, expire, contact, network, (struct sockaddr *)&peering, context);
1715  else
1716  count = reginfo->setTarget(contact_address, expire, contact, network, (struct sockaddr *)&peering, context);
1717  }
1718  if(refresh)
1719  shell::debug(2, "refreshing %s for %ld seconds from %s:%u", getIdent(), (long)interval, contact_host, contact_port);
1720  else if(count) {
1721  time(&reginfo->created);
1722  activated = true;
1723  shell::log(DEBUG1, "registering %s for %ld seconds from %s:%u", getIdent(), (long)interval, contact_host, contact_port);
1724  }
1725  else {
1726  shell::log(shell::ERR, "cannot register %s from %s", getIdent(), buffer);
1727  answer = SIP_FORBIDDEN;
1728  goto reply;
1729  }
1730 
1732  goto reply;
1733 
1734  while(osip_list_eol(OSIP2_LIST_PTR sevent->request->contacts, pos) == 0) {
1735  c = (voip::contact_t)osip_list_get(OSIP2_LIST_PTR sevent->request->contacts, pos++);
1736  if(c && c->url && c->url->username) {
1738  shell::log(shell::INFO, "registering service %s:%s@%s:%s",
1739  c->url->scheme, c->url->username, c->url->host, c->url->port);
1740  }
1741  }
1742 reply:
1743  if(voip::make_response_message(context, sevent->tid, answer, &reply)) {
1744  if(answer == SIP_OK) {
1745  if(reginfo->ext) {
1746  snprintf(buftemp, sizeof(buftemp), "<%s:%d@%s>;expires=%ld",
1747  stack::getScheme(), reginfo->ext, binding, (long)interval);
1749  }
1750 
1751  snprintf(buftemp, sizeof(buftemp), "<%s:%s@%s>;expires=%ld",
1752  stack::getScheme(), reginfo->userid, binding, (long)interval);
1754  }
1755  voip::server_allows(reply);
1756  stack::siplog(reply);
1757  voip::send_response_message(context, sevent->tid, answer, reply);
1758  }
1759  else
1761  if(reginfo && reginfo->is_user() && answer == SIP_OK)
1763 }
1764 
1766 {
1767  bool unreg = false;
1769  if(rr) {
1770  unreg = rr->expire(contact_address);
1771  registry::detach(rr);
1772  }
1773  if(unreg)
1774  shell::log(DEBUG1, "unregister %s", getIdent());
1775 }
1776 
1778 {
1779  assert(rr != NULL);
1780 
1781  linked_pointer<service::keynode> device = server::list("devices");
1782 
1783  while(device) {
1784  linked_pointer<service::keynode> node = device->getFirst();
1785  const char *id, *value;
1786  while(node) {
1787  id = node->getId();
1788  value = node->getPointer();
1789  if(id && value && !stricmp(id, "match")) {
1790  }
1791  node.next();
1792  }
1793  device.next();
1794  }
1795 }
1796 
1798 {
1799  voip::msg_t reply = NULL;
1800 
1802  voip::server_accepts(reply);
1803  voip::server_allows(reply);
1804  stack::siplog(reply);
1806  }
1807  else
1809 }
1810 
1812 {
1813  shutdown_flag = true;
1814  while(active_count)
1815  Thread::sleep(50);
1816  while(shutdown_count < startup_count)
1817  Thread::sleep(50);
1818 }
1819 
1820 void thread::wait(unsigned count) {
1821  while(startup_count < count)
1822  Thread::sleep(50);
1823 }
1824 
1826 {
1827  voip::hdr_t msgheader = NULL;
1828  voip::uri_param_t expires = NULL;
1829  voip::contact_t contact;
1830  int pos = 0;
1831 
1832  assert(sevent->request != NULL);
1833 
1834  header_expires = 0l;
1835  osip_message_get_expires(sevent->request, 0, &msgheader);
1836  if(msgheader && msgheader->hvalue)
1837  header_expires = atol(msgheader->hvalue);
1838  else while(osip_list_eol(OSIP2_LIST_PTR sevent->request->contacts, pos) == 0) {
1839  contact = (voip::contact_t)osip_list_get(OSIP2_LIST_PTR sevent->request->contacts, pos);
1840  if(osip_contact_param_get_byname(contact, (char *)"expires", &expires) != 0 && expires != NULL) {
1841  header_expires = atol(expires->gvalue);
1842  break;
1843  }
1844  ++pos;
1845  }
1846 }
1847 
1848 void thread::run(void)
1849 {
1850  time_t current, prior = 0;
1851  voip::body_t body;
1852 
1853  ++startup_count;
1854  shell::log(DEBUG1, "starting event thread %s", instance);
1855 
1856  for(;;) {
1857  assert(reginfo == NULL);
1858  assert(dialed.keys == NULL);
1859  assert(routed == NULL);
1860  assert(authorized.keys == NULL);
1861  assert(access == NULL);
1862 
1863  display[0] = 0;
1864  extension = 0;
1865  identbuf[0] = 0;
1866 
1867  if(!shutdown_flag)
1869 
1870  activated = false;
1871  accepted = NULL;
1872  via_host = NULL;
1873  via_port = 0;
1874  via_hops = 0;
1875  via_header = NULL;
1876 
1877  if(shutdown_flag) {
1878  shell::log(DEBUG1, "stopping event thread %s", instance);
1880  ++shutdown_count;
1881  return; // exits thread...
1882  }
1883 
1884  time(&current);
1885  if(current != prior) {
1886  prior = current;
1888  }
1889 
1890  if(!sevent)
1891  continue;
1892 
1893  ++active_count;
1894  shell::debug(2, "sip: event %s(%d); cid=%d, did=%d, instance=%s",
1896 
1897  switch(sevent->type) {
1900  shell::debug(4, "sip: registration response %d", sevent->response->status_code);
1901  if(sevent->response && sevent->response->status_code == 401) {
1902  sip_realm = NULL;
1905  if(proxy_auth)
1907  else if(www_auth)
1909  sip_realm = String::unquote(sip_realm, "\"\"");
1911  }
1912  else
1914  break;
1915 #ifndef EXOSIP_API4
1916  case EXOSIP_REGISTRATION_TERMINATED:
1919  break;
1920 #endif
1922 #ifndef EXOSIP_API4
1923  case EXOSIP_REGISTRATION_REFRESHED:
1924 #endif
1927  break;
1931  if(session)
1933  break;
1934  case EXOSIP_CALL_ACK:
1936  authorizing = CALL;
1937  if(sevent->cid <= 0)
1938  break;
1940  if(!session)
1941  break;
1942  session->parent->confirm(this, session);
1943  break;
1944  case EXOSIP_CALL_CANCELLED:
1946  authorizing = CALL;
1947  if(sevent->cid > 0) {
1951  else
1952  break;
1953  }
1954  send_reply(SIP_OK);
1955  break;
1956  case EXOSIP_CALL_NOANSWER:
1958  authorizing = CALL;
1959  if(sevent->cid <= 0)
1960  break;
1962  if(!session)
1963  break;
1965  break;
1966  case EXOSIP_CALL_ANSWERED:
1968  authorizing = CALL;
1969  if(!sevent->response || sevent->cid <= 0)
1970  break;
1972  if(!session)
1973  break;
1974 
1975  switch(session->state) {
1977  case stack::session::REFER:
1978  session->parent->relay(this, session);
1979  default:
1980  break;
1981  }
1982  // copy target sdp into session object...
1983  body = NULL;
1985  if(body && body->body) {
1986  if(media::answer(session, body->body) == NULL) {
1987  session->parent->failed(this, session);
1988  break;
1989  }
1990  }
1991  session->parent->answer(this, session);
1992  break;
1993 #ifndef EXOSIP_API4
1994  case EXOSIP_CALL_TIMEOUT:
1996  authorizing = CALL;
1997  if(sevent->cid <= 0)
1998  break;
2000  if(!session)
2001  break;
2002  session->parent->failed(this, session);
2003  break;
2004 #endif
2011  authorizing = CALL;
2012  if(!sevent->response || sevent->cid <= 0)
2013  break;
2015  if(!session)
2016  break;
2017  shell::debug(4, "sip: call response %d\n", sevent->response->status_code);
2018  switch(sevent->response->status_code) {
2019  case SIP_DECLINE:
2020  case SIP_MOVED_PERMANENTLY:
2021  case SIP_REQUEST_TIME_OUT:
2022  case SIP_SERVER_TIME_OUT:
2025  break;
2026  case SIP_GONE:
2027  case SIP_NOT_FOUND:
2028  case SIP_BUSY_HERE:
2029  case SIP_BUSY_EVRYWHERE:
2031  case SIP_MOVED_TEMPORARILY:
2033  session->parent->busy(this, session);
2034  break;
2035  case SIP_UNAUTHORIZED:
2037  sip_realm = NULL;
2040  if(proxy_auth)
2042  else if(www_auth)
2044  sip_realm = String::unquote(sip_realm, "\"\"");
2045  if(authenticate(session))
2046  break;
2047  // otherwise failed session if cannot authenticate...
2048  default:
2049  session->parent->failed(this, session);
2050  break;
2051  }
2052  break;
2053  case EXOSIP_CALL_CLOSED:
2055  authorizing = CALL;
2056  if(sevent->cid > 0) {
2058  if(session)
2060  else
2061  break;
2062  }
2063  break;
2064  case EXOSIP_CALL_RELEASED:
2066  authorizing = NONE;
2067  if(sevent->cid > 0) {
2068  authorizing = CALL;
2070  if(session)
2072  }
2073  break;
2074  case EXOSIP_CALL_RINGING:
2076  authorizing = NONE;
2077  if(sevent->cid > 0) {
2078  authorizing = CALL;
2080  if(session && session->parent) {
2082  session->parent->ring(this, session);
2083  }
2084  }
2085  break;
2086 
2087  case EXOSIP_CALL_REINVITE:
2089  authorizing = CALL;
2090  if(!sevent->request)
2091  break;
2092  if(sevent->cid < 1 && sevent->did < 1) {
2094  break;
2095  }
2096  expiration();
2098  if(!session) {
2100  break;
2101  };
2102 
2103  session->parent->reinvite(this, session);
2104  break;
2105  case EXOSIP_CALL_INVITE:
2107  authorizing = CALL;
2108  if(!sevent->request)
2109  break;
2110  if(sevent->cid < 1)
2111  break;
2112  expiration();
2114  if(!session) {
2116  break;
2117  }
2118  session->closed = true;
2119  if(authorize())
2120  invite();
2121  break;
2124  authorizing = CALL;
2125  if(!sevent->response)
2126  break;
2127  if(sevent->cid < 1)
2128  break;
2130  if(session)
2131  session->parent->relay(this, session);
2132  break;
2135  authorizing = MESSAGE;
2136  if(!sevent->response)
2137  break;
2138  if(sevent->cid < 1)
2139  break;
2141  if(session)
2143  else
2145  break;
2148  authorizing = CALL;
2149  if(MSG_IS_BYE(sevent->request)) {
2150  if(sevent->cid > 0)
2152  if(session) {
2153  send_reply(SIP_OK);
2154  session->parent->bye(this, session);
2155  }
2156  else
2158  }
2159  else if(MSG_IS_REFER(sevent->request)) {
2160  if(sevent->cid > 0)
2162  if(session)
2164  }
2165  break;
2166  case EXOSIP_MESSAGE_NEW:
2168  authorizing = MESSAGE;
2169  if(!sevent->request)
2170  break;
2171  expiration();
2173  options();
2174  else if(MSG_IS_REGISTER(sevent->request)) {
2176  registration();
2177  }
2178  else if(MSG_IS_REFER(sevent->request)) {
2179  if(sevent->cid > 0)
2181  if(session)
2183  }
2184  else if(MSG_IS_BYE(sevent->request)) {
2185  if(sevent->cid > 0)
2187  if(session) {
2188  send_reply(SIP_OK);
2190  }
2191  else
2193  break;
2194  }
2195  else if(MSG_IS_MESSAGE(sevent->request)) {
2196  if(authorize())
2197  message();
2198  break;
2199  }
2200  else if(MSG_IS_PUBLISH(sevent->request)) {
2201  if(authorize())
2202  publish();
2203  }
2204  else if(!MSG_IS_INFO(sevent->request)) {
2205  shell::debug(2, "unsupported %s in dialog", sevent->request->sip_method);
2206  break;
2207  }
2208  if(sevent->cid > 0) {
2210  if(session)
2212  }
2213  send_reply(SIP_OK);
2214  break;
2215  default:
2216  if(sevent->response)
2218  else
2220  shell::log(shell::WARN, "unknown message");
2221  }
2222 
2223  // release access locks for registry and sessions quickly...
2224 
2225  if(session) {
2227  session = NULL;
2228  }
2229 
2230  if(reginfo) {
2231  if(activated)
2234  reginfo = NULL;
2235  }
2236 
2237  via_address.clear();
2238  request_address.clear();
2239 
2240  // release config access lock(s)...
2241 
2242  if(access) {
2244  access = NULL;
2245  }
2246 
2247  if(routed) {
2249  routed = NULL;
2250  }
2251 
2255  --active_count;
2256  }
2257 }
2258 
2259 } // end namespace
bool unauthenticated(void)
Definition: thread.cpp:669
void update(Socket::address &addr, int changed)
Definition: registry.cpp:1331
Structure for SIP Message (REQUEST and RESPONSE).
Definition: osip_message.h:55
char * subtype
Sub-Type of attachement.
void options(void)
Definition: thread.cpp:1797
Some convenience methods for manipulating SIP uri's.
Definition: uri.h:55
voip::proxyauth_t proxy_auth
Definition: server.h:612
static void automatic_action(context_t ctx)
Definition: voip.cpp:818
static void close(session *s)
Definition: stack.cpp:354
announce a failure.
Definition: eXosip.h:316
user is successfully registred.
Definition: eXosip.h:290
char * port
Port number.
Definition: osip_uri.h:172
char network[MAX_NETWORK_SIZE]
Definition: server.h:269
static void getInterface(struct sockaddr *iface, const struct sockaddr *dest)
Definition: stack.cpp:636
char display[64]
Definition: mapped.h:155
announce a failure.
Definition: eXosip.h:329
static void add_authentication(context_t ctx, const char *user, const char *secret, const char *realm, bool automatic=false)
Definition: voip.cpp:488
osip_list_t contacts
Contacts headers.
Definition: osip_message.h:74
unsigned count
Definition: cgiserver.cpp:92
static volatile char * sip_publish
Definition: service.h:191
#define SESSION_EVENT
Definition: voip.h:148
static bool forward(stack::call *cr)
Definition: stack.cpp:1411
static void release(context_t ctx)
Definition: voip.cpp:877
#define osip_proxy_authenticate_get_realm(header)
Get value of the realm parameter from a Proxy-Authenticate element.
void reregister(const char *contact, time_t interval)
Definition: thread.cpp:1671
static void identity(const struct sockaddr *address, char *buffer, const char *user, size_t size)
Definition: uri.cpp:208
char display[MAX_DISPLAY_SIZE]
Definition: server.h:595
int osip_content_length_to_str(const osip_content_length_t *header, char **dest)
Get a string representation of a Content-Length element.
ACK received for 200ok to INVITE.
Definition: eXosip.h:305
announce a server failure
Definition: eXosip.h:303
static unsigned getRoutes(void)
Definition: server.h:193
announce a 200ok
Definition: eXosip.h:346
registry::mapped * reginfo
Definition: server.h:585
bool authorize(void)
Definition: thread.cpp:700
static cdr * get(void)
Get a free cdr node to fill from the cdr memory pool.
Definition: cdr.cpp:122
static volatile char * sip_contact
Definition: service.h:190
static const char * getDomain(void)
Definition: registry.cpp:115
announce a server failure
Definition: eXosip.h:349
Pointer to a provisioned user xml subtree.
Definition: service.h:119
service::keynode * keys
Definition: service.h:122
User profiles are used to map features and toll restriction level together under a common identifier...
Definition: mapped.h:83
bool expire(Socket::address &addr)
Definition: registry.cpp:1298
char identity[MAX_URI_SIZE]
Definition: server.h:266
#define SIP_NOT_ACCEPTABLE_HERE
Definition: osip_const.h:129
bool is_user(void) const
Definition: mapped.h:128
int osip_atoi(const char *number)
void * osip_list_get(const osip_list_t *li, int pos)
Get an element from a list.
static bool make_answer_response(context_t ctx, tid_t tid, int status, msg_t *msg)
Definition: voip.cpp:587
unsigned extension
Definition: server.h:578
announce new NOTIFY request
Definition: eXosip.h:340
char * port
Port where to send answers.
Definition: osip_via.h:52
static session * create(voip::context_t context, voip::call_t cid, voip::did_t did, voip::tid_t tid)
Definition: stack.cpp:665
static void update(const char *userid)
Definition: messages.cpp:116
char prefix[MAX_USERID_SIZE]
Definition: server.h:141
unsigned from_port
Definition: server.h:607
#define SIP_MOVED_PERMANENTLY
Definition: osip_const.h:100
voip::via_t via_header
Definition: server.h:601
unsigned short param[96]
Definition: cgiserver.cpp:91
struct sockaddr_storage peering
Definition: server.h:274
int did
unique id for SIP dialogs
Definition: eXosip.h:369
static stack::subnet * getPolicy(const struct sockaddr *addr)
Definition: server.cpp:686
#define SIP_ADDRESS_INCOMPLETE
Definition: osip_const.h:125
announce a global failure
Definition: eXosip.h:339
#define USER_PROFILE_OUTGOING
Definition: mapped.h:55
service::keynode * routed
Definition: server.h:584
osip_content_length_t * content_length
Content-Length header.
Definition: osip_message.h:78
uint32_t sequence
Definition: mapped.h:156
osip_contact_t * contact_t
Definition: voip.h:65
#define SIP_SERVER_TIME_OUT
Definition: osip_const.h:137
user is not registred.
Definition: eXosip.h:291
static session * access(voip::call_t cid)
Definition: stack.cpp:687
volatile time_t expires
Definition: mapped.h:113
unsigned cid
Internal call sequence identifiers.
Definition: cdr.h:102
announce processing by a remote app
Definition: eXosip.h:298
announce a 1xx for request.
Definition: eXosip.h:311
Structure for holding Body.
Definition: osip_body.h:48
announce a request failure
Definition: eXosip.h:302
#define MSG_IS_REFER(msg)
Test if the message is a REFER REQUEST.
Definition: osip_message.h:293
unsigned via_hops
Definition: server.h:606
static int getDialog(session *session)
Definition: stack.cpp:449
#define SIP_UNDECIPHERABLE
Definition: osip_const.h:132
static unsigned getRange(void)
Definition: server.h:190
char sysident[MAX_IDENT_SIZE]
Definition: server.h:267
void failed(thread *thread, session *s)
Definition: call.cpp:294
enum sipwitch::cdr::@0 type
Start or end of call?
osip_from_t * from
From header.
Definition: osip_message.h:84
announce a redirection
Definition: eXosip.h:301
announce new incoming request.
Definition: eXosip.h:310
time_t starting
Time the call was received.
Definition: cdr.h:107
call context is cleared.
Definition: eXosip.h:321
service::usernode authorized
Definition: server.h:582
#define MSG_IS_INFO(msg)
Test if the message is an INFO REQUEST.
Definition: osip_message.h:281
static void post(cdr *cdr)
Post cdr record to callbacks through the cdr thread queue.
Definition: cdr.cpp:102
char * type
Type of attachement.
#define osip_message_get_expires(sip, pos, dest)
Find a Expires header.
Definition: osip_parser.h:734
char from[MAX_URI_SIZE+MAX_DISPLAY_SIZE]
Definition: server.h:270
void run(void)
Definition: thread.cpp:1848
osip_uri_t * url
url
Definition: osip_from.h:51
announce a global failure
Definition: eXosip.h:350
announce a 1xx for request.
Definition: eXosip.h:325
static void serviceid(const char *sipuri, char *buffer, size_t size)
Definition: uri.cpp:25
int osip_message_header_get_byname(const osip_message_t *sip, const char *hname, int pos, osip_header_t **dest)
Find an "unknown" header.
osip_content_type_t * content_type
Content-Type header.
Definition: osip_message.h:79
char buftemp[MAX_URI_SIZE]
Definition: server.h:591
static UserCache * find(const char *id)
Find user record.
Definition: cache.cpp:130
announce a redirection
Definition: eXosip.h:347
#define P_SIPWITCH_NODE
Definition: voip.h:155
voip::from_t from
Definition: server.h:602
MappedCall * map
Definition: server.h:348
bool activated
Definition: server.h:588
stack::subnet * access
Definition: server.h:579
void expiration(void)
Definition: thread.cpp:1825
enum sipwitch::thread::@13 authorizing
announce a failure.
Definition: eXosip.h:330
#define osip_via_param_get_byname(header, name, dest)
Find a header parameter in a Via element.
Definition: osip_via.h:199
const char * instance
Definition: server.h:577
static bool authenticate(voip::reg_t id, const char *realm)
Definition: server.cpp:127
union sipwitch::MappedRegistry::@6 source
static int deliver(message *msg)
Definition: messages.cpp:282
void ring(thread *thread, session *s=NULL)
Definition: call.cpp:264
announce new incoming request.
Definition: eXosip.h:324
int cid
unique id for SIP calls (but multiple dialogs!)
Definition: eXosip.h:372
char * sip_realm
Definition: server.h:611
#define SIP_DECLINE
Definition: osip_const.h:141
static void release_event(event_t ev)
Definition: voip.cpp:888
Definition of the Content-Type header.
unsigned addTarget(Socket::address &via, time_t expires, const char *contact, const char *policy, struct sockaddr *peer, voip::context_t context)
Definition: registry.cpp:1388
announce a failure.
Definition: eXosip.h:315
#define WWW_AUTHENTICATE
Definition: osip_const.h:87
#define osip_message_get_subject(sip, pos, dest)
Find a Subject header.
Definition: osip_parser.h:812
void challenge(void)
Definition: thread.cpp:1374
void publish(void)
Definition: thread.cpp:139
#define USER_PROFILE_INCOMING
Definition: mapped.h:54
#define SIP_FORBIDDEN
Definition: osip_const.h:107
osip_via_t * via_t
Definition: voip.h:70
#define SIP_BUSY_EVRYWHERE
Definition: osip_const.h:140
const char * getIdent(void)
Definition: thread.cpp:655
announce a new call
Definition: eXosip.h:294
bool has_feature(unsigned short X) const
Definition: mapped.h:137
voip::to_t to
Definition: server.h:603
static const char * getScheme(void)
Definition: stack.cpp:1032
MappedRegistry * accepted
Definition: server.h:586
#define MSG_IS_REGISTER(msg)
Test if the message is a REGISTER REQUEST.
Definition: osip_message.h:263
static void shutdown(void)
Definition: thread.cpp:1811
void release(void)
Definition: cache.cpp:148
osip_proxy_authenticate_t * proxyauth_t
Definition: voip.h:76
char forward[MAX_USERID_SIZE]
Definition: server.h:314
static void clear(session *s)
Definition: stack.cpp:384
const char *volatile restricted
Definition: server.h:382
char * displayname
Display Name.
Definition: osip_from.h:50
static keynode * getRouting(const char *id)
Definition: server.cpp:764
#define SIP_TEMPORARILY_UNAVAILABLE
Definition: osip_const.h:121
#define SIP_OK
Definition: osip_const.h:97
Socket::address request_address
Definition: server.h:597
static void server_requires(voip::msg_t msg, const char *txt)
Definition: voip.cpp:918
char * username
Username.
Definition: osip_uri.h:169
#define SIP_BUSY_HERE
Definition: osip_const.h:127
struct sockaddr_storage iface
Definition: server.h:409
static bool make_options_response(context_t ctx, tid_t tid, int status, msg_t *msg)
Definition: voip.cpp:565
const char * forwarding
Definition: server.h:349
static void detach(session *s)
Definition: stack.cpp:707
char requesting[MAX_URI_SIZE]
Definition: server.h:596
static const char * getRealm(void)
Definition: server.h:178
enum sipwitch::stack::session::@10 state
static void send_options_response(context_t ctx, tid_t tid, int status, msg_t msg=NULL)
Definition: voip.cpp:579
stack::session * session
Definition: server.h:598
announce a request failure
Definition: eXosip.h:337
destination_t type
Definition: server.h:308
char * gvalue
uri parameter value
Definition: osip_uri.h:57
osip_uri_t * req_uri
Request-Uri (SIP request only)
Definition: osip_message.h:57
announce a 200ok
Definition: eXosip.h:326
char subject[MAX_URI_SIZE]
Definition: server.h:317
static stack sip
Definition: server.h:398
#define osip_free(P)
Definition: osip_port.h:105
static void published(struct sockaddr_storage *peer)
Definition: service.cpp:295
char * response
response
void busy(thread *thread, session *s=NULL)
Definition: call.cpp:643
static const char * referLocal(MappedRegistry *rr, const char *target, char *buffer, size_t size)
Definition: server.cpp:108
#define SIP_GONE
Definition: osip_const.h:113
int osip_list_eol(const osip_list_t *li, int pos)
Check if the end of list is detected .
void trying(thread *thread)
Definition: call.cpp:716
#define SIP_REQUEST_TIME_OUT
Definition: osip_const.h:112
announce new incoming SUBSCRIBE.
Definition: eXosip.h:342
#define MSG_IS_BYE(msg)
Test if the message is a BYE REQUEST.
Definition: osip_message.h:269
char identbuf[MAX_USERID_SIZE+12]
Definition: server.h:592
#define MAX_USERID_SIZE
Definition: mapped.h:69
service::usernode dialed
Definition: server.h:583
struct sipwitch::MappedRegistry::@6::@8 internal
void validate(void)
Definition: thread.cpp:1459
static void release(stack::subnet *access)
Definition: server.cpp:594
Definition of the From header.
Definition: osip_from.h:48
#define MSG_IS_PUBLISH(msg)
Test if the message is an UPDATE REQUEST.
Definition: osip_message.h:333
announce a failure.
Definition: eXosip.h:328
osip_message_t * request
request within current transaction
Definition: eXosip.h:364
const char * via_host
Definition: server.h:605
char dialed[MAX_IDENT_SIZE]
Destination requested on our switch.
Definition: cdr.h:77
#define SIP_NOT_FOUND
Definition: osip_const.h:108
static void registration(voip::reg_t id, modules::regmode_t mode)
Definition: server.cpp:139
static void siplog(voip::msg_t msg)
Definition: stack.cpp:331
static void refer(session *session, voip::event_t sevent)
Definition: stack.cpp:461
bool getsource(void)
Definition: thread.cpp:1409
#define SIP_MOVED_TEMPORARILY
Definition: osip_const.h:101
static mapped * address(const struct sockaddr *addr)
Definition: registry.cpp:869
void registration(void)
Definition: thread.cpp:1551
char sdp[MAX_SDP_BUFFER]
Definition: server.h:265
unsigned invited
Definition: server.h:353
static const char * referRemote(MappedRegistry *rr, const char *target, char *buffer, size_t size)
Definition: server.cpp:89
void message_reply(thread *thread, session *s)
Definition: call.cpp:512
voip::context_t context
Definition: server.h:609
bool offline(void)
Definition: server.h:429
static void incUse(mapped *rr, stats::stat_t stat)
Definition: registry.cpp:139
#define MSG_IS_MESSAGE(msg)
Test if the message is a MESSAGE REQUEST.
Definition: osip_message.h:312
void send_reply(int error)
Definition: thread.cpp:1181
announce a server failure
Definition: eXosip.h:338
char buffer[MAX_URI_SIZE]
Definition: server.h:590
char dialed[MAX_IDENT_SIZE]
Definition: server.h:316
announce no answer
Definition: eXosip.h:344
destination_t destination
Definition: server.h:608
char binding[MAX_URI_SIZE]
Definition: server.h:589
osip_list_t www_authenticates
WWW-Authenticate headers.
Definition: osip_message.h:95
static bool isExtension(const char *id)
Definition: registry.cpp:972
static keynode * list(const char *p)
Definition: service.cpp:320
static void detach(mapped *m)
Definition: registry.cpp:1100
static void send_response_message(context_t ctx, tid_t tid, int status, msg_t msg=NULL)
Definition: voip.cpp:534
unsigned level
Definition: mapped.h:86
static void wait(unsigned count)
Definition: thread.cpp:1820
#define SIP_UNSUPPORTED_URI_SCHEME
Definition: osip_const.h:117
static void send_answer_response(context_t ctx, tid_t tid, int status, msg_t msg=NULL)
Definition: voip.cpp:601
#define osip_message_set_expires(sip, value)
Allocate and Add a new Expires header.
Definition: osip_parser.h:727
static void infomsg(session *session, voip::event_t sevent)
Definition: stack.cpp:497
#define SIP_PROXY_AUTHENTICATION_REQUIRED
Definition: osip_const.h:111
#define SESSION_EXPIRES
Definition: voip.h:140
char * value[96]
Definition: cgiserver.cpp:90
static time_t getExpires(void)
Definition: server.h:184
const char * getId(void)
Definition: server.h:411
announce a failure.
Definition: eXosip.h:314
void bye(thread *thread, session *s)
Definition: call.cpp:231
Socket::address via_address
Definition: server.h:597
void confirm(thread *thread, session *s)
Definition: call.cpp:585
static pattern * getRouting(unsigned trs, const char *id)
Definition: registry.cpp:993
char display[MAX_DISPLAY_SIZE]
Display name of calling party.
Definition: cdr.h:87
Definition of a generic sip header.
Definition: osip_header.h:52
static bool exists(const char *id)
Definition: registry.cpp:1035
static const char * getDigest(void)
Definition: server.h:181
static void getProvision(const char *id, usernode &user)
Definition: server.cpp:850
announce a new INVITE within call
Definition: eXosip.h:295
Socket::address contact_address
Definition: server.h:597
void * context_t
Definition: voip.h:53
announce that call has been cancelled
Definition: eXosip.h:307
announce no answer within the timeout
Definition: eXosip.h:297
char ident[MAX_IDENT_SIZE]
Ident of calling parting.
Definition: cdr.h:72
announce no answer
Definition: eXosip.h:333
osip_list_t vias
Vias headers.
Definition: osip_message.h:94
#define osip_contact_param_get_byname(header, name, dest)
Find a header parameter in a Contact element.
Definition: osip_contact.h:126
eXosip_event_type
Structure for event type description.
Definition: eXosip.h:288
void answer(thread *thread, session *s)
Definition: call.cpp:449
static char * sipAddress(struct sockaddr_internet *addr, char *buf, const char *user=NULL, size_t size=MAX_URI_SIZE)
Definition: stack.cpp:1079
void getDevice(registry::mapped *rr)
Definition: thread.cpp:1777
int osip_message_set_contact(osip_message_t *sip, const char *hvalue)
Set the Contact header.
thread(voip::context_t ctx, const char *tag)
Definition: thread.cpp:45
voip::event_t sevent
Definition: server.h:587
char * host
Host where to send answers.
Definition: osip_via.h:51
void invite(void)
Definition: thread.cpp:349
bool refresh(Socket::address &addr, time_t expires, const char *target_contact)
Definition: registry.cpp:1354
long header_expires
Definition: server.h:600
bool authenticate(void)
Definition: thread.cpp:1263
#define MSG_IS_OPTIONS(msg)
Test if the message is an OPTIONS REQUEST.
Definition: osip_message.h:275
unsigned sequence
Definition: cdr.h:102
char * osip_www_authenticate_get_realm(osip_www_authenticate_t *header)
Get value of the realm parameter from a Www-Authenticate element.
unsigned setTarget(Socket::address &via, time_t expires, const char *contact, const char *policy, struct sockaddr *peer, voip::context_t context)
Definition: registry.cpp:1113
osip_list_t proxy_authenticates
Proxy-Authenticate headers.
Definition: osip_message.h:86
unsigned via_port
Definition: server.h:607
int status_code
Status Code (SIP answer only)
Definition: osip_message.h:60
registry::mapped * reg
Definition: server.h:251
static mapped * access(const char *id)
Definition: registry.cpp:1081
char * body
buffer containing data
Definition: osip_body.h:49
char * scheme
Uri Scheme (sip or sips)
Definition: osip_uri.h:168
announce a failure.
Definition: eXosip.h:313
voip::call_t cid
Definition: server.h:252
void message(void)
Definition: thread.cpp:258
a BYE was received for this call
Definition: eXosip.h:318
announce ringback
Definition: eXosip.h:299
Definition of the Authorization header.
announce a global failure
Definition: eXosip.h:304
announce a 200ok
Definition: eXosip.h:312
static unsigned short sip_port
Definition: service.h:188
osip_message_t * ack
ack within current transaction
Definition: eXosip.h:366
static const char * eid(eXosip_event_type ev)
Definition: thread.cpp:57
static void publish(const char *uri, char *buffer, const char *user, size_t size)
Definition: uri.cpp:127
static const char * get(const char *id)
Definition: digests.cpp:52
static void server_accepts(voip::msg_t msg)
Definition: voip.cpp:907
static unsigned getPrefix(void)
Definition: server.h:187
static void activate(MappedRegistry *rr)
Definition: server.cpp:149
char identity[MAX_USERID_SIZE]
Definition: server.h:593
char * hvalue
Value for header.
Definition: osip_header.h:55
char source[(48+50)]
Definition: mapped.h:154
static void getDialing(const char *id, usernode &user)
Definition: server.cpp:816
char display[MAX_DISPLAY_SIZE]
Definition: server.h:268
static bool make_response_message(context_t ctx, tid_t tid, int status, msg_t *msg)
Definition: voip.cpp:519
void relay(thread *thread, session *s)
Definition: call.cpp:532
const char * contact_host
Definition: server.h:605
Interface class for call detail records.
Definition: cdr.h:56
unsigned contact_port
Definition: server.h:607
announce a 200ok
Definition: eXosip.h:335
void addContact(const char *id)
Definition: registry.cpp:1223
char suffix[MAX_USERID_SIZE]
Definition: server.h:142
int tid
unique id for transactions (to be used for answers)
Definition: eXosip.h:368
announce a redirection
Definition: eXosip.h:336
Structure for referencing url parameters.
Definition: osip_uri.h:55
int osip_message_get_body(const osip_message_t *sip, int pos, osip_body_t **dest)
Get one body header.
char * sip_method
METHOD (SIP request only)
Definition: osip_message.h:58
osip_to_t * to
To header.
Definition: osip_message.h:93
int rid
unique id for registration
Definition: eXosip.h:371
osip_message_t * response
last response within current transaction
Definition: eXosip.h:365
announce start of call
Definition: eXosip.h:300
eXosip_event_type_t type
type of the event
Definition: eXosip.h:360
Structure for referencing SIP urls.
Definition: osip_uri.h:167
#define SIP_SERVICE_UNAVAILABLE
Definition: osip_const.h:136
static void release(const char *hash)
Definition: digests.cpp:68
#define SIP_REQUEST_TERMINATED
Definition: osip_const.h:128
static void setDialog(session *session, voip::did_t did)
Definition: stack.cpp:441
static int inviteRemote(stack::session *session, const char *uri, const char *digest=NULL)
Definition: stack.cpp:1248
char request[MAX_URI_SIZE]
Definition: server.h:318
announce a failure.
Definition: eXosip.h:327
static int inviteLocal(stack::session *session, registry::mapped *rr, destination_t dest)
Definition: stack.cpp:1492
static const char * getValue(keynode *base, const char *id)
Definition: service.cpp:446
static mapped * dialing(const char *id)
Definition: registry.cpp:1055
voip::proxyauth_t www_auth
Definition: server.h:613
static mapped * allocate(const char *id)
Definition: registry.cpp:678
static void server_allows(voip::msg_t msg)
Definition: voip.cpp:912
void reinvite(thread *thread, session *s)
Definition: call.cpp:344
announce a request failure
Definition: eXosip.h:348
struct sockaddr_internet address
Definition: cache.h:96
char dialing[MAX_USERID_SIZE]
Definition: server.h:594
User caches may be used to contact nearby users in multicast registries.
Definition: cache.h:84
int osip_message_get_authorization(const osip_message_t *sip, int pos, osip_authorization_t **dest)
Get one Authorization header.
char uuid[48]
A unique identifier for each and every call.
Definition: cdr.h:67
void deregister(void)
Definition: thread.cpp:1765
static profile_t * getProfile(const char *id)
Definition: server.cpp:703
char network[MAX_NETWORK_SIZE]
Definition: server.h:580
static void header(msg_t msg, const char *key, const char *value)
Definition: voip.cpp:928
treemap< char * > keynode
Definition of a xml node.
Definition: service.h:84
#define SIP_BAD_REQUEST
Definition: osip_const.h:104
#define SIP_UNAUTHORIZED
Definition: osip_const.h:105
static bool announce(MappedRegistry *rr, const char *msgtype, const char *event, const char *expires, const char *body)
Definition: server.cpp:181
static char * answer(stack::session *session, const char *sdp)
Definition: media.cpp:666
#define DEBUG1
Definition: control.h:49
enum sipwitch::MappedRegistry::@5 type
#define MAX_URI_SIZE
Definition: mapped.h:71
struct sockaddr_storage peering
Definition: server.h:581
static event_t get_event(context_t ctx, timeout_t timeout)
Definition: voip.cpp:825
char network[MAX_NETWORK_SIZE *2]
Subnet interface the caller appeared on.
Definition: cdr.h:92
void identify(void)
Definition: thread.cpp:632
char * host
Domain.
Definition: osip_uri.h:171
static mapped * invite(const char *id, stats::stat_t stat)
Definition: registry.cpp:611