SIP Witch 1.9.15
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stack.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 unsigned allocated_segments = 0;
22 static volatile unsigned active_segments = 0;
23 static volatile unsigned allocated_calls = 0;
24 static volatile unsigned allocated_maps = 0;
25 static volatile unsigned active_calls = 0;
26 static unsigned mapped_calls = 0;
27 static LinkedObject *freesegs = NULL;
28 static LinkedObject *freecalls = NULL;
29 static LinkedObject *freemaps = NULL;
30 static LinkedObject **hash = NULL;
31 static unsigned keysize = 177;
32 static condlock_t locking;
33 static mutex_t mapping;
34 
35 stack::background *stack::background::thread = NULL;
36 
37 static bool tobool(const char *s)
38 {
39  assert(s != NULL);
40 
41  switch(*s)
42  {
43  case 'n':
44  case 'N':
45  case 'f':
46  case 'F':
47  case '0':
48  return false;
49  }
50  return true;
51 }
52 
53 stack stack::sip;
54 
55 static const char *ifaddr(const char *addr, const char *id)
56 {
57  if(eq(id, "any") || eq(id, "world") || eq(id, "nat"))
58  return "0.0.0.0/0";
59 
60  return addr;
61 }
62 
63 stack::subnet::subnet(cidr::policy **acl, const char *addr, const char *id) :
64 cidr(acl, ifaddr(addr, id), id)
65 {
66  union {
67  struct sockaddr_storage dest;
68  struct sockaddr_in in;
69 #ifdef AF_INET6
70  struct sockaddr_in6 in6;
71 #endif
72  } us;
73 
74  unsigned char *lp;
75  unsigned bits = getMask();
76  char buf[256];
77 
78  active = true;
79  String::set(netname, sizeof(netname), id);
80 
81  shell::log(DEBUG3, "adding policy %s for %s", id, addr);
82 
83  if(eq(id, "world") || eq(id, "any") || eq(id, "nat")) {
84  if(eq(id, "nat") || eq(id, "any"))
85  String::set(netname, sizeof(netname), "*");
86 
87  if(eq(id, "nat"))
88  service::publish(addr);
89 
90  Socket::address ifs(addr, sip_port);
91  Socket::store(&iface, ifs.getAddr());
92  return;
93  }
94 
95  memset(&us.dest, 0, sizeof(us.dest));
96  us.in.sin_family = Family;
97  switch(Family) {
98  case AF_INET:
99  us.in.sin_port = htons(1);
100  memcpy(&us.in.sin_addr, &Network, sizeof(us.in.sin_addr));
101  lp = ((unsigned char *)(&us.in.sin_addr)) + sizeof(us.in.sin_addr) - 1;
102  if(bits < 31)
103  ++*lp;
104  break;
105 #ifdef AF_INET6
106  case AF_INET6:
107  us.in6.sin6_port = htons(1);
108  memcpy(&us.in6.sin6_addr, &Network, sizeof(us.in6.sin6_addr));
109  lp = ((unsigned char *)(&us.in6.sin6_addr)) + sizeof(us.in6.sin6_addr) - 1;
110  if(bits < 127)
111  ++*lp;
112  break;
113 #endif
114  default:
115  return;
116  }
117  Socket::query((struct sockaddr *)&us.dest, buf, sizeof(buf));
118 
119  if(Socket::via((struct sockaddr *)&iface, (struct sockaddr *)&us.dest))
120  memset(&iface, 0, sizeof(iface));
121  // gateway special rule to specify a gateway public interface...
122  else if(eq(id, "gateway")) {
123  String::set(netname, sizeof(netname), "*");
124  Socket::query((struct sockaddr *)&iface, buf, sizeof(buf));
125  service::publish(buf);
126  }
127  // if interface outside cidr...?
128  else if(!is_member((struct sockaddr *)&iface)) {
129  String::set(netname, sizeof(netname), "*");
131  }
132 }
133 
134 stack::segment::segment(voip::context_t context, call *cr, int cid, int did, int tid) : OrderedObject()
135 {
136  assert(cr != NULL);
137  assert(cid > 0);
138 
139  time_t now;
140 
141  if(!context)
142  context = stack::sip.out_context;
143 
144  ++cr->count;
145  time(&now);
146  enlist(&(cr->segments));
147  sid.context = context;
148  sid.enlist(&hash[cid % keysize]);
149  sid.sequence = (uint32_t)now;
150  sid.sequence &= 0xffffffffl;
151  sid.expires = 0l;
152  sid.nat = NULL;
153  sid.cid = cid;
154  sid.did = did;
155  sid.tid = tid;
156  sid.parent = cr;
158  sid.sdp[0] = 0;
159  sid.reg = NULL;
160  sid.closed = false;
161 
162  secure::uuid(sid.uuid);
163 }
164 
165 void *stack::segment::operator new(size_t size)
166 {
167  assert(size == sizeof(stack::segment));
168 
169  return server::allocate(size, &freesegs, &allocated_segments);
170 }
171 
172 void stack::segment::operator delete(void *obj)
173 {
174  assert(obj != NULL);
175 
176  ((LinkedObject*)(obj))->enlist(&freesegs);
177 }
178 
179 void *stack::call::operator new(size_t size)
180 {
181  assert(size == sizeof(stack::call));
182 
183  ++active_calls;
184  return server::allocate(size, &freecalls, &allocated_calls);
185 }
186 
187 void stack::call::operator delete(void *obj)
188 {
189  assert(obj != NULL);
190 
191  ((LinkedObject*)(obj))->enlist(&freecalls);
192  --active_calls;
193 }
194 
195 stack::background::background(timeout_t iv) : DetachedThread(), Conditional(), expires(Timer::inf)
196 {
197  cancelled = false;
198  signalled = false;
199  interval = iv;
200 }
201 
202 void stack::background::create(timeout_t iv)
203 {
204  thread = new background(iv);
205  thread->start();
206 }
207 
209 {
210  thread->Conditional::lock();
211  thread->cancelled = true;
212  thread->Conditional::signal();
213  thread->Conditional::unlock();
214 }
215 
217 {
218  thread->Conditional::lock();
219  thread->signalled = true;
220  thread->Conditional::signal();
221  thread->Conditional::unlock();
222 }
223 
225 {
226  shell::log(DEBUG1, "starting background thread");
227  timeout_t timeout, current;
228  Timer expiration = interval;
229  time_t then = 0, now;
230  stack::call *next;
231  time_t period = 10;
232 
233  time(&then);
234  then /= period;
235 
236  for(;;) {
237  Conditional::lock();
238  if(cancelled) {
239  Conditional::unlock();
240  shell::log(DEBUG1, "stopping background thread");
241  thread = NULL;
242  return; // exits thread...
243  }
244  timeout = expiration.get();
245  if(!signalled && timeout) {
246  if(timeout > interval)
247  timeout = interval;
248  Conditional::wait(timeout);
249  }
250  timeout = expiration.get();
251  if(signalled || !timeout) {
252  signalled = false;
253  // release lock in case expire calls update timer methods...
254  Conditional::unlock();
255  timeout = interval;
256  locking.access();
257  linked_pointer<stack::call> cp = stack::sip.begin();
258  while(cp) {
259  next = (stack::call *)cp->getNext();
260  current = cp->getTimeout();
261  if(current && current < timeout)
262  timeout = current;
263  cp = next;
264  }
265  locking.release();
266  expiration = timeout;
267  }
268  else {
269  signalled = false;
270  Conditional::unlock();
271  }
272  time(&now);
273  now /= period;
274  if(now > then) {
275  then = now;
276  unsigned released = registry::cleanup(period);
277  if(released)
278  shell::debug(9, "registry cleanup; %d expired", released);
279  else
280  shell::debug(9, "registry cleanup; no entries expired");
281  }
283  }
284 }
285 
287 service::callback(1), mapped_array<MappedCall>(), OrderedIndex()
288 {
289  stacksize = 0;
290  threading = 2;
291  priority = 1;
292  timing = 500;
293  iface = NULL;
294  send101 = 1;
295  dumping = false;
296  incoming = false;
297  outgoing = false;
298  agent = "sipwitch-" VERSION "/eXosip";
299  system = "sipwitch";
300  anon = "anonymous";
301  restricted = trusted = published = proxy = NULL;
302  localnames = "localhost, localhost.localdomain";
303  ring_timer = 4000;
304  cfna_timer = 16000;
305  reset_timer = 6000;
306  invite_expires = 120;
307 }
308 
309 void stack::release(void)
310 {
311  LinkedObject::release();
312 }
313 
315 {
316  stack::sip.dumping = false;
317 }
318 
320 {
321  ::remove(DEFAULT_VARPATH "/log/sipdump.log");
322  ::remove(_STR(control::path("controls") + "/sipdump.log"));
323 }
324 
326 {
327  clearDumping();
328  stack::sip.dumping = true;
329 }
330 
332 {
333  fsys_t log;
334  char *text = NULL;
335  size_t tlen;
336 
337  if(!msg || !stack::sip.dumping)
338  return;
339 
340  osip_message_to_str(msg, &text, &tlen);
341  if(text) {
342  log.open(control::env("siplogs"), fsys::GROUP_PRIVATE, fsys::APPEND);
343  if(is(log)) {
344  Mutex::protect(&stack::sip.dumping);
345  log.write(text, tlen);
346  log.write("---\n\n", 5);
347  Mutex::release(&stack::sip.dumping);
348  log.close();
349  }
350  osip_free(text);
351  }
352 }
353 
355 {
356  assert(s != NULL);
357 
358  call *cr;
359 
360  if(!s)
361  return;
362 
363  cr = s->parent;
364 
365  if(!s->closed) {
366  if(s == cr->source)
368  else
370  s->closed = true;
371  }
372 
373  Mutex::protect(cr);
374  if(s->state != session::CLOSED) {
375  s->state = session::CLOSED;
376  if(s == cr->source)
377  cr->terminateLocked();
378  else
379  cr->closingLocked(s);
380  }
381  Mutex::release(cr);
382 }
383 
385 {
386  assert(s != NULL);
387 
388  call *cr;
389 
390  if(!s)
391  return;
392 
393  cr = s->parent;
394 
395  if(!s->closed) {
396  if(s == cr->source)
398  else
400  s->closed = true;
401  }
402 
403  Mutex::protect(cr);
404 
405  if(--cr->count == 0) {
406  shell::debug(4, "clearing call %08x:%u\n",
407  cr->source->sequence, cr->source->cid);
408  Mutex::release(cr);
409  destroy(cr);
410  return;
411  }
412 
413  if(s->cid > 0) {
414  Mutex::release(cr);
415  locking.exclusive();
416  shell::debug(4, "clearing call %08x:%u session %08x:%u\n",
417  cr->source->sequence, cr->source->cid, s->sequence, s->cid);
418  if(s->state != session::CLOSED) {
419  s->state = session::CLOSED;
420  voip::release_call(s->context, s->cid, s->did);
421  }
422  s->delist(&hash[s->cid % keysize]);
423  s->cid = 0;
424  s->did = -1;
425  locking.share();
426  }
427  else
428  Mutex::release(cr);
429 }
430 
432 {
433  assert(s != NULL);
434 
435  if(!s || !s->parent)
436  return;
437 
438  destroy(s->parent);
439 }
440 
442 {
443  assert(s != NULL && s->parent != NULL);
444  Mutex::protect(s->parent);
445  s->did = did;
446  Mutex::release(s->parent);
447 }
448 
450 {
451  voip::did_t did = -1;
452 
453  if(s && s->parent) {
454  Mutex::protect(s->parent);
455  did = s->did;
456  Mutex::release(s->parent);
457  }
458  return did;
459 }
460 
461 void stack::refer(session *source, voip::event_t sevent)
462 {
463  assert(source);
464  assert(sevent);
465 
466  voip::hdr_t header = NULL;
467  voip::msg_t msg = NULL;
468  session *target = NULL;
469  call *cr = source->parent;
470  voip::did_t did;
471 
472  if(cr->source == source)
473  target = cr->target;
474  else if(cr->target == source)
475  target = cr->source;
476 
477  osip_message_header_get_byname(sevent->request, "Refer-To", 0, &header);
478  if(!header || !header->hvalue)
479  goto failed;
480 
481  did = getDialog(target);
482  if(did < 1)
483  goto failed;
484 
485  if(!voip::make_dialog_refer(target->context, did, header->hvalue, &msg)) {
486 failed:
488  return;
489  }
490  voip::server_allows(msg);
491  voip::header(msg, "Referred-By", source->identity);
492  voip::send_dialog_message(target->context, did, msg);
493  target->state = session::REFER;
494  target->tid = sevent->tid;
495 }
496 
497 void stack::infomsg(session *source, voip::event_t sevent)
498 {
499  assert(source);
500  assert(sevent);
501 
502  char type[128];
503  voip::ctype_t ct;
504  voip::msg_t msg = NULL;
505  voip::body_t body = NULL;
506  session *target = NULL;
507  call *cr = source->parent;
508 
509  if(cr->source == source)
510  target = cr->target;
511  else if(cr->target == source)
512  target = cr->source;
513 
514  voip::did_t did = getDialog(target);
515  if(did < 1)
516  return;
517 
518  ct = sevent->request->content_type;
519  if(!ct || !ct->type)
520  return;
521 
522  osip_message_get_body(sevent->request, 0, &body);
523  if(!voip::make_dialog_info(target->context, did, &msg))
524  return;
525  if(ct->subtype)
526  snprintf(type, sizeof(type), "%s/%s", ct->type, ct->subtype);
527  else
528  snprintf(type, sizeof(type), "%s", ct->type);
529  voip::attach(msg, type, body->body);
530  voip::server_allows(msg);
531  voip::send_dialog_message(target->context, did, msg);
532 }
533 
535 {
536  assert(cr != NULL);
537 
538  linked_pointer<segment> sp = cr->segments.begin();
539  while(sp) {
540  session *s = sp->get();
541  if(s != cr->source) {
542  if(!s->closed) {
544  s->closed = true;
545  }
546  if(s->cid > 0 && s->state != session::CLOSED) {
547  voip::release_call(s->context, s->cid, s->did);
548  s->state = session::CLOSED;
549  }
550  }
551  sp.next();
552  }
553 }
554 
556 {
557  assert(cr != NULL);
558  MappedCall *map;
559 
560  linked_pointer<segment> sp;
561 
562  cdr *clog = cr->log();
563 
564  // we assume access lock was already held when we call this...
565 
566  locking.exclusive();
567  sp = cr->segments.begin();
568  while(sp) {
569  --active_segments;
570  segment *next = sp.getNext();
571 
572  if(!sp->sid.closed) {
573  if(&(sp->sid) == cr->source)
574  registry::decUse(sp->sid.reg, stats::INCOMING);
575  else
576  registry::decUse(sp->sid.reg, stats::OUTGOING);
577  sp->sid.closed = true;
578  }
579 
580  if(sp->sid.cid > 0) {
581  if(sp->sid.state != session::CLOSED) {
582  voip::release_call(sp->sid.context, sp->sid.cid, sp->sid.did);
583  }
584  sp->sid.delist(&hash[sp->sid.cid % keysize]);
585  }
586  if(sp->sid.nat)
587  media::release(&sp->sid.nat);
588  delete *sp;
589  sp = next;
590  }
591  map = cr->map;
592  cr->delist();
593  delete cr;
594  locking.share();
595  release(map);
596  if(clog)
597  cdr::post(clog);
598 }
599 
601 {
602  if(map) {
603  String::set(map->state, sizeof(map->state), "-");
604  map->created = map->active = 0;
605  mapping.lock();
606  map->enlist(&freemaps);
607  mapping.release();
608  }
609 }
610 
612 {
613  MappedCall *map = NULL;
614 
615  mapping.lock();
616  if(freemaps) {
617  map = (MappedCall *)freemaps;
618  freemaps = map->getNext();
619  }
620  else if(allocated_maps < mapped_calls)
621  map = sip(allocated_maps++);
622  mapping.release();
623  if(!map)
624  return NULL;
625 
626  String::set(map->state, sizeof(map->state), "iinit");
627  map->active = 0;
628  map->authorized[0] = 0;
629  map->source[0] = 0;
630  map->target[0] = 0;
631 
632  time(&map->created);
633  return map;
634 }
635 
636 void stack::getInterface(struct sockaddr *iface, const struct sockaddr *dest)
637 {
638  assert(iface != NULL && dest != NULL);
639 
640  Socket::via(iface, dest);
641  switch(iface->sa_family) {
642  case AF_INET:
643  ((struct sockaddr_in*)(iface))->sin_port = htons(sip_port);
644  break;
645 #ifdef AF_INET6
646  case AF_INET6:
647  ((struct sockaddr_in6*)(iface))->sin6_port = htons(sip_port);
648  break;
649 #endif
650  }
651 }
652 
654 {
655  assert(cr != NULL);
656  assert(cid > 0);
657 
658  locking.exclusive();
659  segment *sp = new segment(context, cr, cid);
660  ++cr->invited;
661  locking.share();
662  return &sp->sid;
663 }
664 
666 {
667  assert(cid > 0);
668 
669  MappedCall *map = get();
670 
671  if(!map)
672  return NULL;
673 
674  call *cr;
675  segment *sp;
676 
677  locking.modify();
678  cr = new call;
679  sp = new segment(context, cr, cid, did, tid); // after count set to 0!
680  cr->source = &(sp->sid);
681  cr->map = map;
682 
683  locking.share();
684  return cr->source;
685 }
686 
688 {
689  assert(cid > 0);
690 
691  linked_pointer<session> sp;
692 
693  locking.access();
694  sp = hash[cid % keysize];
695  while(sp) {
696  if(sp->cid == cid)
697  break;
698  sp.next();
699  }
700  if(!sp) {
701  locking.release();
702  return NULL;
703  }
704  return *sp;
705 }
706 
708 {
709  if(s)
710  locking.release();
711 }
712 
714 {
715  assert(cfg != NULL);
716 
717 #ifdef EXOSIP_API4
718  unsigned ver = 4;
719 #else
720  unsigned ver = 3;
721 #endif
722 
723  if(!iface && sip_iface)
724  iface = sip_iface;
725 
726  thread *thr;
727  shell::log(DEBUG1, "starting sip stack v%d; %d maps", ver, mapped_calls);
728 
729  mapped_array<MappedCall>::create(control::env("callmap"), mapped_calls);
730  if(!sip)
731  shell::log(shell::FAIL, "calls could not be mapped");
732  initialize();
733 
734 #ifdef HAVE_TLS
735  if(sip_tlsmode) {
736  eXosip_tls_ctx_t ctx;
737  int ctx_error;
738 
739  memset(&ctx, 0, sizeof(ctx));
740  String::set(ctx.random_file, sizeof(ctx.random_file),
741  sip_tlsdev);
742  String::set(ctx.dh_param, sizeof(ctx.dh_param),
743  sip_tlsdh);
744  String::set(ctx.root_ca_cert, sizeof(ctx.root_ca_cert),
745  sip_tlsca);
746  String::set(ctx.server.cert, sizeof(ctx.server.cert),
747  sip_tlscert);
748  String::set(ctx.server.priv_key, sizeof(ctx.server.priv_key),
749  sip_tlskey);
750  String::set(ctx.server.priv_key_pw, sizeof(ctx.server.priv_key_pw),
751  sip_tlspwd);
752  if ((ctx_error = eXosip_set_tls_ctx(&ctx)) != TLS_OK)
753  shell::log(shell::FAIL,
754  "sip set tls credentials failed %i", ctx_error);
755  }
756 #endif
757 
758 #if UCOMMON_ABI > 5
759  Socket::query(sip_family);
760 #else
761  Socket::family(sip_family);
762 #endif
763  osip_trace_initialize_syslog(TRACE_LEVEL0, (char *)"sipwitch");
764 
765  if(sip_protocol == IPPROTO_TCP) {
769  }
770  else {
774  }
775 
776 #ifdef HAVE_TLS
777  voip::create(&tls_context, agent, family);
778 #endif
779 
780 #if defined(EXOSIP2_OPTION_SEND_101) && !defined(EXOSIP_API4)
781  eXosip_set_option(EXOSIP_OPT_DONT_SEND_101, &send101);
782 #endif
783 
784  threading = 0;
785  if(udp_context) {
786  ++threading;
787  if(!voip::listen(udp_context, IPPROTO_UDP, iface, sip_port))
788  shell::log(shell::FAIL, "cannot listen port %u for udp", sip_port);
789  else
790  shell::log(shell::NOTIFY, "listening port %u for udp", sip_port);
791  thr = new thread(udp_context, "udp");
792  thr->start(priority);
793  }
794 
795  if(tcp_context) {
796  ++threading;
797  if(!voip::listen(tcp_context, IPPROTO_TCP, iface, sip_port))
798  shell::log(shell::FAIL, "cannot listen port %u for tcp", sip_port);
799  shell::log(shell::NOTIFY, "listening port %u for tcp", sip_port);
800  thr = new thread(tcp_context, "tcp");
801  thr->start(priority);
802 
803  }
804 
805  if(tls_context) {
806  ++threading;
807  if(!voip::listen(tls_context, IPPROTO_TCP, iface, sip_port, true))
808  shell::log(shell::FAIL, "cannot listen port %u for tls", sip_port + 1);
809  shell::log(shell::NOTIFY, "listening port %u for tls", sip_port + 1);
810  thr = new thread(tls_context, "tls");
811  thr->start(priority);
812  }
813 
816 }
817 
819 {
820  assert(cfg != NULL);
821 
822  shell::log(DEBUG1, "stopping sip stack");
825  Thread::yield();
826  MappedMemory::release();
827  MappedMemory::remove(control::env("callmap"));
828 }
829 
830 bool stack::check(void)
831 {
832  if(tcp_context) {
833  shell::log(shell::INFO, "checking tcp context...");
836  }
837  if(udp_context) {
838  shell::log(shell::INFO, "checking udp context...");
841  }
842  if(tls_context) {
843  shell::log(shell::INFO, "checking tls context...");
846  }
847  return true;
848 }
849 
850 void stack::snapshot(FILE *fp)
851 {
852  assert(fp != NULL);
853 
854  linked_pointer<call> cp;
855  fprintf(fp, "SIP:\n");
856  locking.access();
857  fprintf(fp, " mapped calls: %d\n", mapped_calls);
858  fprintf(fp, " active calls: %d\n", active_calls);
859  fprintf(fp, " active sessions: %d\n", active_segments);
860  fprintf(fp, " allocated calls: %d\n", allocated_calls);
861  fprintf(fp, " allocated sessions: %d\n", allocated_segments);
862  cp = begin();
863  while(cp) {
864  cp.next();
865  }
866  locking.release();
867 }
868 
870 {
871  assert(cfg != NULL);
872 
873  const char *new_proxy = NULL;
874  const char *key = NULL, *value;
875  linked_pointer<service::keynode> sp = cfg->getList("stack");
876  linked_pointer<service::keynode> tp = cfg->getList("timers");
877  int val;
878  const char *localhosts = "localhost, localhost.localdomain";
879 
880  unsigned cfna_value = 0;
881  unsigned ring_value = 0;
882  unsigned reset_value = 0;
883 
884  char buf[256];
885  if(!gethostname(buf, sizeof(buf))) {
886  String::add(buf, sizeof(buf), ", localhost, localhost.localdomainb");
887  localhosts = buf;
888  }
889 
891 
892  while(sp) {
893  key = sp->getId();
894  value = sp->getPointer();
895  if(key && value) {
896  if(eq(key, "threading") && !is_configured())
897  threading = atoi(value);
898  else if(eq(key, "priority") && !is_configured())
899  priority = atoi(value);
900  else if(eq(key, "timing"))
901  timing = atoi(value);
902  else if(eq(key, "incoming"))
903  incoming = tobool(value);
904  else if(eq(key, "outgoing"))
905  outgoing = tobool(value);
906  else if(eq(key, "trace") || eq(key, "dumping"))
907  dumping = tobool(value);
908  else if(eq(key, "keysize") && !is_configured())
909  keysize = atoi(value);
910  else if(eq(key, "interface") && !is_configured()) {
911  sip_family = AF_INET;
912  sip_iface = NULL;
913 #ifdef AF_INET6
914  if(strchr(value, ':') != NULL)
915  sip_family = AF_INET6;
916 #endif
917  if(eq(value, ":::") || eq(value, "::0") || eq(value, "::*") || eq(value, "*") || eq(value, "0.0.0.0") || !*value)
918  value = NULL;
919  if(value)
920  value = strdup(value);
921  sip_iface = value;
922  }
923  else if(eq(key, "send101") && !is_configured() && tobool(value))
924  send101 = 0;
925  else if(eq(key, "keepalive") && !is_configured()) {
926  val = atoi(value);
928  }
929  else if(eq(key, "learn") && !is_configured()) {
930  val = tobool(value);
932  }
933  else if(eq(key, "restricted")) {
934  if(eq(value, "none"))
935  restricted = NULL;
936  else
937  restricted = cfg->dup(value);
938  }
939  else if(eq(key, "localnames"))
940  localhosts = cfg->dup(value);
941  else if(eq(key, "trusted")) {
942  if(eq(value, "none"))
943  trusted = NULL;
944  else
945  trusted = cfg->dup(value);
946  }
947  else if(eq(key, "system"))
948  system = value;
949  else if(eq(key, "anon"))
950  anon = value;
951  else if(eq(key, "contact"))
952  cfg->setContact(value);
953  else if(eq(key, "published") || eq(key, "public"))
954  published = cfg->dup(value);
955  else if(eq(key, "peering") || eq(key, "gateway"))
956  service::publish(value);
957  else if(eq(key, "proxy") || eq(key, "outbound"))
958  new_proxy = cfg->dup(value);
959  else if(eq(key, "agent") && !is_configured())
960  agent = value;
961  else if(eq(key, "port") && !is_configured())
962  sip_port = atoi(value);
963  else if(eq(key, "mapped") && !is_configured())
964  mapped_calls = atoi(value);
965  else if(eq(key, "password") && !is_configured())
966  sip_tlspwd = strdup(value);
967  else if(eq(key, "keyfile") && !is_configured())
968  sip_tlskey = strdup(value);
969  else if(eq(key, "random") && !is_configured())
970  sip_tlsdev = strdup(value);
971  else if(eq(key, "certfile") && !is_configured())
972  sip_tlscert = strdup(value);
973  else if(eq(key, "dhfile") && !is_configured())
974  sip_tlsdh = strdup(value);
975  else if(eq(key, "authfile") && !is_configured())
976  sip_tlsca = strdup(value);
977  else if(eq(key, "transport") && !is_configured()) {
978  if(eq(value, "tcp") || eq(value, "tls"))
979  sip_protocol = IPPROTO_TCP;
980  if(eq(value, "tls"))
981  sip_tlsmode = 1;
982  }
983  }
984  sp.next();
985  }
986 
987  while(is(tp)) {
988  key = tp->getId();
989  value = tp->getPointer();
990  if(key && value) {
991  if(eq(key, "ring"))
992  ring_value = atoi(value);
993  else if(eq(key, "cfna"))
994  cfna_value = atoi(value);
995  else if(eq(key, "reset"))
996  reset_value = atoi(value);
997  else if(eq(key, "invite"))
998  invite_expires = atoi(value);
999  }
1000  tp.next();
1001  }
1002 
1003  localnames = localhosts;
1004  proxy = new_proxy;
1005 
1006  if(sip_family != AF_INET)
1008 
1009  if(ring_value && ring_value < 100)
1010  ring_timer = ring_value * 1000l;
1011  else if(ring_value >= 100)
1012  ring_timer = ring_value;
1013 
1014  if(cfna_value && cfna_value < 1000)
1015  cfna_timer = ring_timer *cfna_value;
1016  else if(cfna_value >= 1000)
1017  cfna_timer = cfna_value;
1018 
1019  if(reset_value && reset_value < 100)
1020  reset_timer = reset_value * 1000l;
1021  else if(reset_value >= 100)
1022  reset_timer = reset_value;
1023 
1024  if(!mapped_calls)
1025  mapped_calls = registry::getEntries();
1026  if(!hash) {
1027  hash = new LinkedObject*[keysize];
1028  memset(hash, 0, sizeof(LinkedObject *) * keysize);
1029  }
1030 }
1031 
1032 const char *stack::getScheme(void)
1033 {
1034  if(sip_tlsmode)
1035  return "sips";
1036  return "sip";
1037 }
1038 
1039 char *stack::sipPublish(struct sockaddr_internet *addr, char *buf, const char *user, size_t size)
1040 {
1041  assert(addr != NULL);
1042  assert(buf != NULL);
1043  assert(user == NULL || *user != 0);
1044  assert(size > 0);
1045 
1046  char pbuf[10];
1047  bool ipv6 = false;
1048 
1049  if(sip.published == NULL)
1050  return sipAddress(addr, buf, user, size);
1051 
1052  if(sip_tlsmode)
1053  String::set(buf, size, "sips:");
1054  else
1055  String::set(buf, size, "sip:");
1056 
1057  if(strchr(sip.published, ':'))
1058  ipv6 = true;
1059 
1060  if(user) {
1061  String::add(buf, size, user);
1062  if(ipv6)
1063  String::add(buf, size, "@[");
1064  else
1065  String::add(buf, size, "@");
1066  }
1067  else if(ipv6)
1068  String::add(buf, size, "[");
1069 
1070  String::add(buf, size, sip.published);
1071  if(ipv6)
1072  snprintf(pbuf, sizeof(pbuf), "]:%u", sip_port);
1073  else
1074  snprintf(pbuf, sizeof(pbuf), ":%u", sip_port);
1075  String::add(buf, size, pbuf);
1076  return buf;
1077 }
1078 
1079 char *stack::sipAddress(struct sockaddr_internet *addr, char *buf, const char *user, size_t size)
1080 {
1081  assert(addr != NULL);
1082  assert(buf != NULL);
1083  assert(user == NULL || *user != 0);
1084  assert(size > 0);
1085 
1086  char pbuf[10];
1087  unsigned port = 0;
1088  bool ipv6 = false;
1089  const char *defaddr = NULL;
1090 
1091  *buf = 0;
1092  size_t len;
1093 
1094  if(!size)
1095  size = MAX_URI_SIZE;
1096 
1097  if(!addr)
1098  return NULL;
1099 
1100  switch(addr->address.sa_family) {
1101  case AF_INET:
1102  port = ntohs(addr->ipv4.sin_port);
1103  break;
1104 #ifdef AF_INET6
1105  case AF_INET6:
1106  ipv6 = true;
1107  port = ntohs(addr->ipv6.sin6_port);
1108  break;
1109 #endif
1110  default:
1111  defaddr = registry::getDomain();
1112  }
1113  if(!port)
1114  port = sip_port;
1115 
1116  if(sip_tlsmode)
1117  String::set(buf, size, "sips:");
1118  else
1119  String::set(buf, size, "sip:");
1120 
1121  if(user) {
1122  String::add(buf, size, user);
1123  if(ipv6)
1124  String::add(buf, size, "@[");
1125  else
1126  String::add(buf, size, "@");
1127  }
1128  else if(ipv6)
1129  String::add(buf, size, "[");
1130 
1131  if(defaddr) {
1132  String::add(buf, sizeof(buf), defaddr);
1133  return buf;
1134  }
1135 
1136  len = strlen(buf);
1137  Socket::query((struct sockaddr *)addr, buf + len, size - len);
1138  if(ipv6)
1139  snprintf(pbuf, sizeof(pbuf), "]:%u", port);
1140  else
1141  snprintf(pbuf, sizeof(pbuf), ":%u", port);
1142  String::add(buf, size, pbuf);
1143  return buf;
1144 }
1145 
1146 Socket::address *stack::getAddress(const char *addr, Socket::address *ap)
1147 {
1148  assert(addr != NULL && *addr != 0);
1149 
1150  char buffer[MAX_URI_SIZE];
1151  int family = sip_family;
1152  const char *svc = "sip";
1153  const char *sp;
1154  char *ep;
1155 
1156  sp = strchr(addr, '<');
1157  if(sp)
1158  addr = ++sp;
1159 
1160  if(!strnicmp(addr, "sip:", 4))
1161  addr += 4;
1162  else if(!strnicmp(addr, "sips:", 5))
1163  addr += 5;
1164 
1165  if(strchr(addr, '@'))
1166  addr = strchr(addr, '@') + 1;
1167 
1168 #ifdef AF_INET6
1169  if(*addr == '[') {
1170  String::set(buffer, sizeof(buffer), ++addr);
1171  if(sp) {
1172  ep = strchr(buffer, '>');
1173  if(ep)
1174  *ep = 0;
1175  }
1176  family = AF_INET6;
1177  ep = strchr(buffer, ']');
1178  if(ep)
1179  *(ep++) = 0;
1180  if(*ep == ':')
1181  svc = ++ep;
1182  goto set;
1183  }
1184 #endif
1185  String::set(buffer, sizeof(buffer), addr);
1186  if(sp) {
1187  ep = (char *)strchr(buffer, '>');
1188  if(ep)
1189  *ep = 0;
1190  }
1191  ep = strchr(buffer, ':');
1192  if(ep) {
1193  *(ep++) = 0;
1194  svc = ep;
1195  }
1196 
1197 set:
1198  if(svc) {
1199  ep = (char *)strchr(svc, ';');
1200  if(ep)
1201  *ep = 0;
1202  }
1203 
1204  if(ap)
1205  ap->add(buffer, svc, family);
1206  else
1207  ap = new Socket::address(family, buffer, svc);
1208 
1209  if(ap && !ap->getList()) {
1210  delete ap;
1211  ap = NULL;
1212  }
1213  return ap;
1214 }
1215 
1217 {
1218  char route[MAX_URI_SIZE];
1219  char touri[MAX_URI_SIZE];
1220 
1221  if(!call->diverting)
1222  return;
1223 
1224  uri::publish(call->request, route, call->divert, sizeof(route));
1225 
1226  if(String::equal(call->diverting, "all")) {
1227  snprintf(touri, sizeof(touri), "<%s>;reason=unconditional", route);
1228  voip::header(invite, "Diversion", touri);
1229  }
1230  else if(String::equal(call->diverting, "na")) {
1231  snprintf(touri, sizeof(touri), "<%s>;reason=no-answer", route);
1232  voip::header(invite, "Diversion", touri);
1233  }
1234  else if(String::equal(call->diverting, "busy")) {
1235  snprintf(touri, sizeof(touri), "<%s>;reason=user-busy", route);
1236  voip::header(invite, "Diversion", touri);
1237  }
1238  else if(String::equal(call->diverting, "dnd")) {
1239  snprintf(touri, sizeof(touri), "<%s>;reason=do-not-disturb", route);
1240  voip::header(invite, "Diversion", touri);
1241  }
1242  else if(String::equal(call->diverting, "away")) {
1243  snprintf(touri, sizeof(touri), "<%s>;reason=away", route);
1244  voip::header(invite, "Diversion", touri);
1245  }
1246 }
1247 
1248 int stack::inviteRemote(stack::session *s, const char *uri_target, const char *digest)
1249 {
1250  assert(s != NULL && s->parent != NULL);
1251  assert(uri_target != NULL);
1252 
1253  stack::session *invited;
1254  stack::call *call = s->parent;
1255  linked_pointer<stack::segment> sp = call->segments.begin();
1256  char username[MAX_USERID_SIZE];
1257  char network[MAX_NETWORK_SIZE];
1258  char touri[MAX_URI_SIZE];
1259  char route[MAX_URI_SIZE];
1260  voip::msg_t invite = NULL;
1261  char expheader[32];
1262  char seqid[64];
1263  int cid;
1264  unsigned icount = 0;
1265  time_t now;
1266  srv resolv;
1267  struct sockaddr_storage peering;
1268  voip::context_t context = resolv.route(uri_target, route, sizeof(route));
1269  const char *schema = NULL;
1270  char rewrite[MAX_URI_SIZE];
1271 
1272  if(!context)
1273  return icount;
1274 
1275 /*
1276  struct sockaddr_storage peering, abuf;
1277  voip::context_t context = stack::sip.out_context;
1278  const char *out_target = uri_target;
1279  char rewrite[MAX_URI_SIZE];
1280  const char *schema = server::resolve(out_target, &abuf);
1281 */
1282 
1283  if(eq(uri_target, "tcp:", 4)) {
1284  uri_target += 4;
1285  schema = "sip";
1286  }
1287  else if(eq(uri_target, "udp:", 4)) {
1288  uri_target += 4;
1289  schema = "sip";
1290  }
1291 
1292  if(schema) {
1293  snprintf(rewrite, sizeof(rewrite), "%s:%s", schema, uri_target);
1294  uri_target = rewrite;
1295  }
1296 
1297  time(&now);
1298 
1299  // compute network and subnet..
1300  String::set(network, sizeof(network), "*");
1301  uri::userid(uri_target, username, sizeof(username));
1302 
1304  if(subnet) {
1305  memcpy(&peering, &subnet->iface, sizeof(struct sockaddr_storage));
1306  String::set(network, sizeof(network), subnet->getId());
1307  }
1308  else
1309  service::published(&peering);
1310  server::release(subnet);
1311 
1312  // make sure we do not re-invite an existing active member again
1313  while(is(sp)) {
1314  if(!stricmp(sp->sid.identity, uri_target) && sp->sid.state != stack::session::CLOSED)
1315  return icount;
1316  sp.next();
1317  }
1318 
1319  snprintf(touri, sizeof(touri), "<%s>", uri_target);
1320 
1321  invite = NULL;
1322 
1323  if(!voip::make_invite_request(context, touri, s->from, call->subject, &invite, route)) {
1324  shell::log(shell::ERR, "cannot invite %s; build failed", uri_target);
1325  return icount;
1326  }
1327 
1328  divert(call, invite);
1329 
1330  voip::server_allows(invite);
1331  voip::server_supports(invite, "100rel,replaces,timer");
1332 
1333  if(digest && s->reg) {
1334  char *authbuf = new char[1024];
1335  stringbuf<64> response;
1336  stringbuf<64> once;
1337  char nounce[64];
1338  char *req = NULL;
1339  osip_uri_to_str(invite->req_uri, &req);
1340  snprintf(authbuf, 1024, "%s:%s", invite->sip_method, req);
1341  Random::uuid(nounce);
1342 
1343  digest_t auth("md5");
1344  auth.puts(nounce);
1345  once = *auth;
1346  auth = registry::getDigest();
1347  auth.puts(authbuf);
1348  response = *auth;
1349  snprintf(authbuf, 1024, "%s:%s:%s", digest, *once, *response);
1350  auth.reset();
1351  auth.puts(authbuf);
1352  response = *auth;
1353  snprintf(authbuf, 1024,
1354  "Digest username=\"%s\""
1355  ",realm=\"%s\""
1356  ",uri=\"%s\""
1357  ",response=\"%s\""
1358  ",nonce=\"%s\""
1359  ",algorithm=%s"
1360  ,s->reg->userid, registry::getRealm(), req, *response, *once, registry::getDigest());
1361  voip::header(invite, AUTHORIZATION, authbuf);
1362  delete[] authbuf;
1363  osip_free(req);
1364  }
1365  else
1366  voip::header(invite, P_SIPWITCH_NODE, "no");
1367 
1368  if(call->expires) {
1369  snprintf(expheader, sizeof(expheader), "%ld", (long)(call->expires - now));
1370  voip::header(invite, SESSION_EXPIRES, expheader);
1371  }
1372 
1373  char sdp[MAX_SDP_BUFFER];
1374  LinkedObject *nat = NULL;
1375 
1376  if(media::invite(s, network, &nat, sdp) == NULL) {
1377  shell::log(shell::ERR, "cannot assign media proxy for %s", uri_target);
1378  voip::free_message_request(context, invite);
1379  return icount;
1380  }
1381 
1382  voip::attach(invite, SDP_BODY, sdp);
1383  stack::siplog(invite);
1384  cid = voip::send_invite_request(context, invite);
1385  if(cid > 0) {
1386  snprintf(seqid, sizeof(seqid), "%08x-%d", s->sequence, s->cid);
1387  uri::publish(call->request, route, seqid, sizeof(route));
1388  voip::call_reference(context, cid, route);
1389  ++icount;
1390  }
1391  else {
1392  media::release(&nat);
1393  shell::log(shell::ERR, "invite failed for %s", uri_target);
1394  return icount;
1395  }
1396 
1397  invited = stack::create(context, call, cid);
1399  String::set(invited->identity, sizeof(invited->identity), uri_target);
1400  String::set(invited->display, sizeof(invited->display), username);
1401  snprintf(invited->from, sizeof(invited->from), "<%s>", uri_target);
1402  String::set(invited->network, sizeof(invited->network), network);
1403  invited->nat = nat;
1404  uri::identity(*resolv, invited->sysident, username, sizeof(invited->sysident));
1405  invited->peering = peering;
1406 
1407  shell::debug(3, "inviting %s\n", uri_target);
1408  return icount;
1409 }
1410 
1412 {
1413  unsigned invited = cr->invited;
1414 
1415 repeat:
1416  service::usernode user;
1417  service::keynode *fwd;
1418  const char *forwarding = cr->forwarding;
1419  const char *target;
1420  char buffer[MAX_URI_SIZE];
1421  registry::mapped *rr = NULL;
1422 
1423  String::set(cr->divert, sizeof(cr->divert), cr->forward);
1424  cr->forwarding = NULL;
1425  cr->diverting = NULL;
1426 
1427  if(!forwarding)
1428  return false;
1429 
1430  server::getProvision(cr->forward, user);
1431  if(!user.keys)
1432  return false;
1433 
1434  fwd = user.keys->getChild("forwarding");
1435  if(!fwd)
1436  goto failed;
1437 
1438  target = server::getValue(fwd, forwarding);
1439 
1440  if((!target || !*target) && (String::equal(forwarding, "away") || String::equal(forwarding, "dnd")))
1441  target = server::getValue(fwd, "busy");
1442 
1443  if(!target || !*target)
1444  goto failed;
1445 
1446  cr->diverting = forwarding;
1447 
1448  if(strchr(target, '@'))
1449  goto remote;
1450 
1451  String::set(cr->forward, sizeof(cr->forward), target);
1452  target = cr->forward;
1453  server::release(user);
1454 
1455  shell::debug(3, "call forward <%s> to %s", forwarding, target);
1456 
1457  rr = registry::access(target);
1458  if(rr) {
1459  cr->forwarding = "na";
1460  inviteLocal(cr->source, rr, FORWARDED);
1461  if(cr->forwarding && !String::equal("na", cr->forwarding) && cr->invited == invited) {
1462  registry::detach(rr);
1463  goto repeat;
1464  }
1465  registry::detach(rr);
1466  }
1467 
1468  goto test;
1469 
1470 remote:
1471  if(!String::equal(target, "sip:", 4) && !String::equal(target, "sips:", 5))
1472  snprintf(buffer, sizeof(buffer), "%s:%s", getScheme(), target);
1473  else
1474  String::set(buffer, sizeof(buffer), target);
1475  target = buffer;
1476  server::release(user);
1477  shell::debug(3, "call forward <%s> to %s", forwarding, target);
1478  inviteRemote(cr->source, target);
1479  goto test;
1480 
1481 failed:
1482  server::release(user);
1483  return false;
1484 
1485 test:
1486  if(cr->invited > invited)
1487  return true;
1488 
1489  return false;
1490 }
1491 
1493 {
1494  assert(s != NULL && s->parent != NULL);
1495  assert(rr != NULL);
1496 
1497  linked_pointer<registry::target> tp = rr->source.internal.targets;
1498  stack::session *invited;
1499  stack::call *call = s->parent;
1500  linked_pointer<stack::segment> sp = call->segments.begin();
1501  LinkedObject *nat;
1502  char sdp[MAX_SDP_BUFFER];
1503 
1504  time_t now;
1505  voip::msg_t invite;
1506  char expheader[32];
1507  char seqid[64];
1508  char route[MAX_URI_SIZE];
1509  char touri[MAX_URI_SIZE];
1510  int cid;
1511  unsigned icount = 0;
1512 
1513  time(&now);
1514 
1515  if(rr->expires && rr->expires < now + 1)
1516  return icount;
1517 
1518  // make sure we do not re-invite an existing active member again
1519  while(is(sp)) {
1520  if(sp->sid.reg == rr && sp->sid.state == stack::session::OPEN) {
1521  return icount;
1522  }
1523  sp.next();
1524  }
1525 
1526  while(is(tp)) {
1527  invited = NULL;
1528  if(tp->expires && tp->expires < now + 1)
1529  goto next;
1530 
1531  switch(tp->status) {
1532  case registry::target::BUSY: // can still try invite...
1534  break;
1535  default:
1536  goto next;
1537  }
1538 
1539  invite = NULL;
1540 
1541  if(dest == ROUTED) {
1542  stack::sipPublish(&tp->address, route, call->dialed, sizeof(route));
1543  snprintf(touri, sizeof(touri), "\"%s\" <%s;user=phone>", call->dialed, route);
1544  }
1545  else if(call->phone)
1546  snprintf(touri, sizeof(touri), "<%s;user=phone>", tp->contact);
1547  else
1548  snprintf(touri, sizeof(touri), "<%s>", tp->contact);
1549 
1550  stack::sipPublish(&tp->address, route + 1, NULL, sizeof(route) - 5);
1551  route[0] = '<';
1552  String::add(route, sizeof(route), ";lr>");
1553 
1554  if(!voip::make_invite_request(tp->context, touri, s->from, call->subject, &invite, route)) {
1555  stack::sipPublish(&tp->address, route, NULL, sizeof(route));
1556  shell::log(shell::ERR, "cannot invite %s; build failed", route);
1557  goto next;
1558  }
1559 
1560  // if not routing, then separate to from request-uri for forwarding
1561  if(dest != ROUTED) {
1562  stack::sipPublish(&tp->address, route, call->dialed, sizeof(route));
1563  if(call->phone)
1564  String::add(route, sizeof(route), ";user=phone");
1565  snprintf(touri, sizeof(touri), "\"%s\" <%s>", call->dialed, route);
1566  if(invite->to) {
1567  osip_to_free(invite->to);
1568  invite->to = NULL;
1569  }
1570  osip_message_set_to(invite, touri);
1571  }
1572 
1573  divert(call, invite);
1574 
1575  voip::server_allows(invite);
1576  voip::server_supports(invite, "100rel,replaces,timer");
1577 
1578  if(call->expires) {
1579  snprintf(expheader, sizeof(expheader), "%ld", (long)(call->expires - now));
1580  voip::header(invite, SESSION_EXPIRES, expheader);
1581  }
1582 
1583  nat = NULL;
1584  if(media::invite(s, tp->network, &nat, sdp) == NULL) {
1585  stack::sipPublish(&tp->address, route, NULL, sizeof(route));
1586  shell::log(shell::ERR, "no media proxy available for %s", route);
1587  voip::free_message_request(tp->context, invite);
1588  goto next;
1589  }
1590 
1591  voip::attach(invite, SDP_BODY, sdp);
1592  stack::siplog(invite);
1593  cid = voip::send_invite_request(tp->context, invite);
1594  if(cid > 0) {
1595  snprintf(seqid, sizeof(seqid), "%08x-%d", s->sequence, s->cid);
1596  stack::sipAddress((struct sockaddr_internet *)&tp->peering, route, seqid, sizeof(route));
1597  voip::call_reference(tp->context, cid, route);
1598  ++icount;
1599  }
1600  else {
1601  media::release(&nat);
1602  stack::sipPublish(&tp->address, route, NULL, sizeof(route));
1603  shell::log(shell::ERR, "invite failed for %s", route);
1604  goto next;
1605  }
1606 
1607  invited = stack::create(tp->context, call, cid);
1608 
1609  String::set(invited->network, sizeof(invited->network), tp->network);
1610  invited->peering = tp->peering;
1611  invited->nat = nat;
1612 
1613  if(rr->ext)
1614  snprintf(invited->sysident, sizeof(invited->sysident), "%u", rr->ext);
1615  else
1616  String::set(invited->sysident, sizeof(invited->sysident), rr->userid);
1617  if(rr->display[0])
1618  String::set(invited->display, sizeof(invited->display), rr->display);
1619  else
1620  String::set(invited->display, sizeof(invited->display), invited->sysident);
1621  stack::sipPublish((struct sockaddr_internet *)&tp->peering, invited->identity, invited->sysident, sizeof(invited->identity));
1622  if(rr->ext && !rr->display[0])
1623  snprintf(invited->from, sizeof(invited->from),
1624  "\"%s\" <%s;user=phone>", invited->sysident, invited->identity);
1625  else if(rr->display[0])
1626  snprintf(invited->from, sizeof(invited->from),
1627  "\"%s\" <%s>", rr->display, invited->identity);
1628  else
1629  snprintf(invited->from, sizeof(invited->from),
1630  "<%s>", invited->identity);
1632  invited->reg = rr;
1633 
1634  stack::sipPublish(&tp->address, route, NULL, sizeof(route));
1635  switch(dest) {
1636  case ROUTED:
1637  shell::debug(3, "routing to %s\n", route);
1638  break;
1639  default:
1640  shell::debug(3, "inviting %s\n", route);
1641  }
1642 
1643 next:
1644  tp.next();
1645  }
1646 
1647  if(call->count > 0 || call->forwarding == NULL)
1648  return icount;
1649 
1650  switch(rr->status) {
1651  case MappedRegistry::BUSY:
1652  call->forwarding = "busy";
1653  return icount;
1655  call->forwarding = "gone";
1656  return icount;
1657  case MappedRegistry::DND:
1658  call->forwarding = "dnd";
1659  return icount;
1660  case MappedRegistry::AWAY:
1661  call->forwarding = "away";
1662  return icount;
1663  default:
1664  break;
1665  }
1666  return icount;
1667 }
1668 
1669 } // end namespace
static void lock(context_t ctx)
Definition: voip.h:54
Structure for SIP Message (REQUEST and RESPONSE).
Definition: osip_message.h:55
char * subtype
Sub-Type of attachement.
static void call_reference(context_t ctx, call_t cid, void *route)
Definition: voip.cpp:472
static void close(session *s)
Definition: stack.cpp:354
int osip_uri_to_str(const osip_uri_t *url, char **dest)
Get a string representation of a url element.
char network[MAX_NETWORK_SIZE]
Definition: server.h:269
static void getInterface(struct sockaddr *iface, const struct sockaddr *dest)
Definition: stack.cpp:636
bool check(void)
Definition: stack.cpp:830
static bool forward(stack::call *cr)
Definition: stack.cpp:1411
static void identity(const struct sockaddr *address, char *buffer, const char *user, size_t size)
Definition: uri.cpp:208
static void divert(stack::call *cr, voip::msg_t msg)
Definition: stack.cpp:1216
static bool userid(const char *sipuri, char *buffer, size_t size)
Definition: uri.cpp:73
static void unlock(context_t ctx)
Definition: voip.h:55
static String path(const char *id)
Get a string from a server environment variable.
Definition: control.h:141
static voip::context_t udp_context
Definition: service.h:235
static const char * getDomain(void)
Definition: registry.cpp:115
static Socket::address * getAddress(const char *uri, Socket::address *addr=NULL)
Definition: stack.cpp:1146
const char *volatile trusted
Definition: server.h:383
Pointer to a provisioned user xml subtree.
Definition: service.h:119
service::keynode * keys
Definition: service.h:122
static voip::context_t tls_context
Definition: service.h:236
static unsigned getEntries(void)
Definition: registry.cpp:606
char identity[MAX_URI_SIZE]
Definition: server.h:266
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 automatic(void)
Definition: messages.cpp:341
void start(service *cfg)
Definition: stack.cpp:713
static void destroy(session *s)
Definition: stack.cpp:431
void osip_trace_initialize_syslog(osip_trace_level_t level, char *ident)
String anon
Definition: server.h:389
Structure for event description.
Definition: eXosip.h:359
const char *volatile published
Definition: server.h:384
struct sockaddr_storage peering
Definition: server.h:274
void reload(service *cfg)
Definition: stack.cpp:869
timeout_t reset_timer
Definition: server.h:392
static stack::subnet * getPolicy(const struct sockaddr *addr)
Definition: server.cpp:686
static char * sipPublish(struct sockaddr_internet *addr, char *buf, const char *user=NULL, size_t size=MAX_URI_SIZE)
Definition: stack.cpp:1039
bool dumping
Definition: server.h:390
String agent
Definition: server.h:387
void osip_to_free(osip_to_t *header)
Free a To element.
keynode * getList(const char *path)
Definition: service.cpp:376
static session * access(voip::call_t cid)
Definition: stack.cpp:687
volatile time_t expires
Definition: mapped.h:113
static void notify(void)
Definition: stack.cpp:216
LinkedObject * nat
Definition: server.h:273
const char * iface
Definition: server.h:386
static unsigned cleanup(time_t period)
Definition: registry.cpp:452
Structure for holding Body.
Definition: osip_body.h:48
static int getDialog(session *session)
Definition: stack.cpp:449
char sysident[MAX_IDENT_SIZE]
Definition: server.h:267
timeout_t cfna_timer
Definition: server.h:392
#define DEBUG3
Definition: control.h:51
segment(voip::context_t context, call *cr, voip::call_t cid, voip::did_t did=-1, voip::tid_t tid=0)
Definition: stack.cpp:134
static char * invite(stack::session *session, const char *target, LinkedObject **nat, char *sdp, size_t size=MAX_SDP_BUFFER)
Definition: media.cpp:696
static void post(cdr *cdr)
Post cdr record to callbacks through the cdr thread queue.
Definition: cdr.cpp:102
char * type
Type of attachement.
char from[MAX_URI_SIZE+MAX_DISPLAY_SIZE]
Definition: server.h:270
void release(void)
Definition: stack.cpp:309
int osip_message_header_get_byname(const osip_message_t *sip, const char *hname, int pos, osip_header_t **dest)
Find an "unknown" header.
static void publish(const char *addr)
Set and publish public "appearing" address of the server.
Definition: service.cpp:272
voip::context_t context
Definition: server.h:255
osip_content_type_t * content_type
Content-Type header.
Definition: osip_message.h:79
#define P_SIPWITCH_NODE
Definition: voip.h:155
MappedCall * map
Definition: server.h:348
destination_t
Definition: server.h:48
union sipwitch::MappedRegistry::@6 source
static voip::context_t tcp_context
Definition: service.h:234
void closingLocked(session *s)
Definition: call.cpp:185
static call_t send_invite_request(context_t ctx, msg_t msg)
Definition: voip.cpp:555
Definition of the Content-Type header.
static void send_dialog_message(context_t ctx, did_t did, msg_t msg)
Definition: voip.cpp:802
static const char * sip_iface
Definition: service.h:189
#define EXOSIP_OPT_UDP_LEARN_PORT
int *: specific re-usage of "rport"
Definition: eX_setup.h:100
static bool make_dialog_info(context_t ctx, did_t did, msg_t *msg)
Definition: voip.cpp:770
char state[16]
Definition: mapped.h:152
int call_t
Definition: voip.h:62
volatile int timing
Definition: server.h:379
char target[(48+50)]
Definition: mapped.h:154
static unsigned allocate(void)
Definition: server.cpp:1025
friend class proxy
Definition: server.h:221
void setContact(const char *text)
Definition: service.h:309
int tid_t
Definition: voip.h:60
friend class thread
Definition: server.h:222
char authorized[48]
Definition: mapped.h:153
static void disjoin(call *cr)
Definition: stack.cpp:534
timeout_t ring_timer
Definition: server.h:392
static const char * getScheme(void)
Definition: stack.cpp:1032
session * source
Definition: server.h:345
static void shutdown(void)
Definition: thread.cpp:1811
int osip_message_set_to(osip_message_t *sip, const char *hvalue)
Set the To header.
const char * diverting
Definition: server.h:350
char forward[MAX_USERID_SIZE]
Definition: server.h:314
char dh_param[1024]
absolute path to a file necessary for diffie hellman key exchange
Definition: eX_setup.h:173
static void clear(session *s)
Definition: stack.cpp:384
const char *volatile restricted
Definition: server.h:382
static void enableDumping(void)
Definition: stack.cpp:325
static void create(timeout_t interval)
Definition: stack.cpp:202
bool incoming
Definition: server.h:390
struct sockaddr_storage iface
Definition: server.h:409
static background * thread
Definition: server.h:234
const char * forwarding
Definition: server.h:349
static void detach(session *s)
Definition: stack.cpp:707
static const char * getRealm(void)
Definition: server.h:178
enum sipwitch::stack::session::@10 state
void stop(service *cfg)
Definition: stack.cpp:818
timeout_t getTimeout(void)
Definition: call.cpp:737
String system
Definition: server.h:388
char random_file[1024]
absolute path to a file with random(!) data
Definition: eX_setup.h:172
osip_uri_t * req_uri
Request-Uri (SIP request only)
Definition: osip_message.h:57
unsigned threading
Definition: server.h:376
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
subnet(cidr::policy **acl, const char *rule, const char *name)
Definition: stack.cpp:63
Representation of an active call record.
Definition: mapped.h:147
session * target
Definition: server.h:346
#define MAX_USERID_SIZE
Definition: mapped.h:69
int eXosip_set_option(struct eXosip_t *excontext, int opt, const void *value)
Set eXosip options.
#define SDP_BODY
Definition: voip.h:151
struct sipwitch::MappedRegistry::@6::@8 internal
static void release(stack::subnet *access)
Definition: server.cpp:594
osip_message_t * request
request within current transaction
Definition: eXosip.h:364
static bool listen(context_t ctx, int proto=IPPROTO_UDP, const char *iface=NULL, unsigned port=5060, bool tls=false)
Definition: voip.cpp:832
static bool is_configured(void)
Definition: service.h:217
static void siplog(voip::msg_t msg)
Definition: stack.cpp:331
static void attach(msg_t msg, const char *type, const char *body)
Definition: voip.cpp:941
static void refer(session *session, voip::event_t sevent)
Definition: stack.cpp:461
static void server_supports(voip::msg_t msg, const char *txt)
Definition: voip.cpp:923
char sdp[MAX_SDP_BUFFER]
Definition: server.h:265
char priv_key_pw[1024]
Definition: eX_setup.h:162
unsigned invited
Definition: server.h:353
static const char * sip_tlskey
Definition: service.h:202
static const char * sip_domain
Definition: service.h:196
static void incUse(mapped *rr, stats::stat_t stat)
Definition: registry.cpp:139
static void release_call(context_t ctx, call_t cid, did_t did)
Definition: voip.cpp:653
static const char * sip_tlsdh
Definition: service.h:201
char dialed[MAX_IDENT_SIZE]
Definition: server.h:316
structure to describe the whole TLS-context for eXosip consists of a certificate, a corresponding pri...
Definition: eX_setup.h:171
static void detach(mapped *m)
Definition: registry.cpp:1100
static const char * sip_tlsca
Definition: service.h:200
static void enableIPV6(void)
Definition: media.cpp:520
int osip_message_to_str(osip_message_t *sip, char **dest, size_t *message_length)
Get a string representation of a osip_message_t element.
static void wait(unsigned count)
Definition: thread.cpp:1820
unsigned invite_expires
Definition: server.h:393
eXosip_tls_credentials_t server
credential of the server
Definition: eX_setup.h:176
static void send_answer_response(context_t ctx, tid_t tid, int status, msg_t msg=NULL)
Definition: voip.cpp:601
static void infomsg(session *session, voip::event_t sevent)
Definition: stack.cpp:497
#define SESSION_EXPIRES
Definition: voip.h:140
char * value[96]
Definition: cgiserver.cpp:90
char netname[MAX_NETWORK_SIZE]
Definition: server.h:403
const char * getId(void)
Definition: server.h:411
Definition of a generic sip header.
Definition: osip_header.h:52
static const char * getDigest(void)
Definition: server.h:181
static void getProvision(const char *id, usernode &user)
Definition: server.cpp:850
static void free_message_request(context_t ctx, voip::msg_t msg)
Definition: voip.cpp:497
voip::context_t route(const char *uri, char *buf, size_t size)
Definition: srv.cpp:375
void * context_t
Definition: voip.h:53
static void cancel(void)
Definition: stack.cpp:208
#define AUTHORIZATION
Definition: osip_const.h:40
#define EXOSIP_OPT_UDP_KEEP_ALIVE
int *: interval for keep alive packets (UDP, TCP, TLS, DTLS)
Definition: eX_setup.h:99
static void disableDumping(void)
Definition: stack.cpp:314
static char * sipAddress(struct sockaddr_internet *addr, char *buf, const char *user=NULL, size_t size=MAX_URI_SIZE)
Definition: stack.cpp:1079
static void clearDumping(void)
Definition: stack.cpp:319
int did_t
Definition: voip.h:61
static voip::context_t out_context
Definition: service.h:233
#define MAX_SDP_BUFFER
Definition: mapped.h:72
void release(void)
Definition: media.cpp:447
static void option(context_t ctx, int opt, const void *value)
Definition: voip.cpp:479
OrderedIndex segments
Definition: server.h:342
static const char * sip_tlsdev
Definition: service.h:199
void terminateLocked(void)
Definition: call.cpp:50
static const char * sip_tlscert
Definition: service.h:203
static bool make_dialog_refer(context_t ctx, did_t did, const char *to, msg_t *msg)
Definition: voip.cpp:754
const char *volatile localnames
Definition: server.h:381
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
voip::call_t cid
Definition: server.h:252
System configuration instance and service functions.
Definition: service.h:78
void snapshot(FILE *fp)
Definition: stack.cpp:850
static unsigned short sip_port
Definition: service.h:188
static void publish(const char *uri, char *buffer, const char *user, size_t size)
Definition: uri.cpp:127
char * hvalue
Value for header.
Definition: osip_header.h:55
char source[(48+50)]
Definition: mapped.h:154
char display[MAX_DISPLAY_SIZE]
Definition: server.h:268
Interface class for call detail records.
Definition: cdr.h:56
char root_ca_cert[1024]
absolute path to the file with known rootCAs
Definition: eX_setup.h:174
int tid
unique id for transactions (to be used for answers)
Definition: eXosip.h:368
static void decUse(mapped *rr, stats::stat_t stat)
Definition: registry.cpp:167
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
yippieh, everything is fine :)
Definition: eX_setup.h:183
char * map[96]
Definition: cgiserver.cpp:89
static bool make_invite_request(context_t ctx, const char *to, const char *from, const char *subject, msg_t *msg, const char *route=NULL)
Definition: voip.cpp:542
#define SIP_SERVICE_UNAVAILABLE
Definition: osip_const.h:136
static void setDialog(session *session, voip::did_t did)
Definition: stack.cpp:441
background(timeout_t sync)
Definition: stack.cpp:195
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
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 const char * sip_tlspwd
Definition: service.h:198
unsigned priority
Definition: server.h:376
cdr * log(void)
Definition: call.cpp:799
static void server_allows(voip::msg_t msg)
Definition: voip.cpp:912
char divert[MAX_USERID_SIZE]
Definition: server.h:315
static MappedCall * get(void)
Definition: stack.cpp:611
bool outgoing
Definition: server.h:390
static const char * env(const char *id)
Return the value of a server environment variable.
Definition: control.h:131
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 MAX_NETWORK_SIZE
Definition: mapped.h:66
#define DEBUG1
Definition: control.h:49
#define MAX_URI_SIZE
Definition: mapped.h:71
static void create(context_t *ctx, const char *agent, int family=AF_INET)
Definition: voip.cpp:856
size_t stacksize
Definition: server.h:377