nua_register.c 39.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2006 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

/**@CFILE nua_register.c
 * @brief REGISTER and registrations
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 *
 * @date Created: Wed Mar  8 11:48:49 EET 2006 ppessi
 */

#include "config.h"

#include <sofia-sip/string0.h>
36
#include <sofia-sip/su_strlst.h>
37 38 39 40 41
#include <sofia-sip/sha1.h>
#include <sofia-sip/su_uniqueid.h>
#include <sofia-sip/token64.h>
#include <sofia-sip/su_tagarg.h>

42
#include <sofia-sip/sip_protos.h>
43
#include <sofia-sip/sip_util.h>
44
#include <sofia-sip/sip_status.h>
45 46 47

#define NTA_LEG_MAGIC_T      struct nua_handle_s
#define NTA_OUTGOING_MAGIC_T struct nua_handle_s
48
#define NTA_UPDATE_MAGIC_T   struct nua_s
49

50
#include "nua_stack.h"
51
#include <sofia-sip/nta_tport.h>
52 53 54 55 56

#if HAVE_SIGCOMP
#include <sigcomp.h>
#endif

57 58 59 60 61 62 63
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#include <assert.h>

64 65 66 67
#if !defined(random) && defined(_WIN32)
#define random rand
#endif

68 69
typedef struct register_usage register_usage;
typedef struct register_owner_vtable register_owner_vtable;
70 71

int register_usage_init(register_usage *ru,
72
			register_owner_vtable const *owner_methods,
73 74 75 76 77
			su_root_t *root,
			nta_agent_t *agent);

int register_usage_set_features(register_usage *ru, char *features);

78 79 80 81
int register_usage_check_for_nat(struct register_usage *ru,
				 nta_outgoing_t *orq,
				 sip_t const *sip);

82 83 84 85 86 87 88
int register_usage_contacts_from_via(register_usage *ru,
				     sip_via_t const *via,
				     sip_via_t const *pair);

int register_usage_set_contact(struct register_usage *ru,
			       sip_contact_t *m);

89 90 91 92 93
int register_usages_from_via(struct register_usage **list,
			     nua_owner_t *owner,
			     sip_via_t const *via,
			     int public);

94 95 96 97 98 99 100 101
int register_usage_set_contact_by_aor(struct register_usage *ru,
				      url_t const *aor,
				      register_usage const *defaults);

register_usage *register_usage_by_aor(register_usage const *usages,
				      url_t const *aor,
				      int only_default);

102 103 104
void register_usage_start_keepalive(struct register_usage *ru,
				    unsigned interval,
				    nta_outgoing_t *register_trans);
105

106
void register_usage_stop_keepalive(struct register_usage *ru);
107

108
int register_usage_check_accept(sip_accept_t const *accept);
109

110 111 112
int register_usage_process_options(struct register_usage *usages,
				   nta_incoming_t *irq,
				   sip_t const *sip);
113

114
sip_contact_t const *register_usage_contact(register_usage const *ru);
115

116 117
char const * const register_usage_content_type;
nua_usage_class const *nua_register_usage;
118

119
struct register_owner_vtable
120
{
121 122 123 124 125 126 127 128 129 130 131
  int ro_size;
  int (*ro_status)(nua_owner_t *, register_usage *ru,
		   int status, char const *phrase,
		   tag_type_t tag, tag_value_t value, ...);
  int (*ro_report_probe_error)(nua_owner_t *, register_usage *ru,
			       int status, char const *phrase,
			       tag_type_t tag, tag_value_t value, ...);
  int (*ro_report_keepalive_error)(nua_owner_t *, register_usage *ru,
				   int status, char const *phrase,
				   tag_type_t tag, tag_value_t value, ...);
};
132

133 134
/* ====================================================================== */
/* Register usage */
135

136 137 138
struct register_usage {
  struct register_usage *ru_next, **ru_prev; /* Doubly linked list */
  unsigned ru_default:1, ru_secure:1, ru_public:1;
139

140
  unsigned ru_by_application:1, ru_add_contact:1;
141

142 143 144 145 146 147 148 149 150 151 152 153 154 155
  /* The registration state machine. */
  /**< Initial REGISTER containing ru_rcontact has been sent */
  unsigned ru_registering:1;
  /**< 2XX response to REGISTER containg ru_rcontact has been received */
  unsigned ru_registered:1;
  /**< The registration has been validated:
   *   We have successfully sent OPTIONS to ourselves.
   */
  unsigned ru_validated:1;
  /**< The registration has been validated once.
   *   We have successfully sent OPTIONS to ourselves, so do not give
   *   up if OPTIONS probe fails.
   */
  unsigned ru_once_validated:1;
156

157
  unsigned :0;
158

159

160 161 162 163 164
  register_owner_vtable 
  const *ru_ro;			/**< Callbacks */
  nua_owner_t *ru_owner;	/**< Backpointer */
  su_root_t *ru_root;		/**< Root for timers and stuff */
  nta_agent_t *ru_nta;		/**< SIP transactions */
165

166
  char ru_cookie[32];		/**< Our magic cookie */
167

168 169 170
#if HAVE_SIGCOMP
  struct sigcomp_compartment *ru_compartment;
#endif
171

172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
  tport_t *ru_tport;		/**< Transport used when registered */
  char const *ru_features;	/**< Feature parameters for rcontact */
  sip_via_t *ru_via;		/**< Our Via (or Via pair) */
  sip_contact_t *ru_rcontact;	/**< Our contact */
  sip_contact_t *ru_dcontact;	/**< Contact for dialogs */
  sip_contact_t *ru_previous;	/**< Stale contact */
  sip_contact_t *ru_gruu;	/**< Contact added to requests */
  sip_route_t *ru_route;	/**< Outgoing Service-Route */
  sip_path_t *ru_path;		/**< Incoming Path */
  sip_contact_t *ru_obp;	/**< Contacts from outbound proxy */

  char *ru_nat_detected;	/**< Our public address */
  char *ru_nat_port;		/**< Our public port number */

  void *ru_stun;		/**< Stun context */
  void *ru_upnp;		/**< UPnP context  */

  char *ru_sipstun;		/**< Stun server usable for keep-alives */
  unsigned ru_keepalive;	/**< Interval. */
  su_timer_t *ru_kalt;		/**< Keep-alive timer */
  msg_t *ru_kalmsg;		/**< Keep-alive OPTIONS message */
  nta_outgoing_t *ru_kalo;	/**< Keep-alive OPTIONS transaction */
};
195

196 197 198
/* ======================================================================== */
/* REGISTER */

199 200
static void restart_register(nua_handle_t *nh, tagi_t *tags);
static void refresh_register(nua_handle_t *, nua_dialog_usage_t *, sip_time_t);
201 202 203 204 205

static int process_response_to_register(nua_handle_t *nh,
					nta_outgoing_t *orq,
					sip_t const *sip);

206 207
static void unregister_expires_contacts(msg_t *msg, sip_t *sip);

208
static char *nua_stack_register_features(nua_handle_t *nh);
209

210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
static int nua_stack_register_status(nua_handle_t *, register_usage *ru,
				     int status, char const *phrase,
				     tag_type_t tag, tag_value_t value, ...);

static int nua_stack_register_failed(nua_handle_t *, register_usage *ru,
				     int status, char const *phrase,
				     tag_type_t tag, tag_value_t value, ...);

register_owner_vtable nua_stack_register_callbacks = {
    sizeof nua_stack_register_callbacks,
    nua_stack_register_status,
    nua_stack_register_failed,
    nua_stack_register_failed,
  };

225
int
226 227
nua_stack_register(nua_t *nua, nua_handle_t *nh, nua_event_t e,
		   tagi_t const *tags)
228 229
{
  nua_dialog_usage_t *du;
230
  struct register_usage *ru = NULL;
231 232 233
  struct nua_client_request *cr = nh->nh_cr;
  msg_t *msg = NULL;
  sip_t *sip;
234
  int terminating = e != nua_r_register;
235 236 237 238 239 240

  if (nh->nh_special && nh->nh_special != nua_r_register)
    return UA_EVENT2(e, 500, "Invalid handle for REGISTER");
  if (cr->cr_orq)
    return UA_EVENT2(e, 500, "Request already in progress");

241
  nua_stack_init_handle(nua, nh, nh_has_register, "", TAG_NEXT(tags));
242
  nh->nh_special = nua_r_register;
243

244
  du = nua_dialog_usage_add(nh, nh->nh_ds, nua_register_usage, NULL);
245 246
  if (!du)
    return UA_EVENT1(e, NUA_500_ERROR);
247 248
  ru = nua_dialog_usage_private(du); assert(ru);

249 250
  register_usage_init(ru, &nua_stack_register_callbacks, 
		      nh->nh_nua->nua_root, nh->nh_nua->nua_nta);
251
  register_usage_set_features(ru, nua_stack_register_features(nh));
252

253 254
  register_usage_stop_keepalive(ru);

255 256
  if (du->du_msg)
    cr->cr_msg = msg_ref_create(du->du_msg);
257

258
  msg = nua_creq_msg(nua, nh, cr, cr->cr_msg != NULL,
259
		     SIP_METHOD_REGISTER,
260
		     TAG_IF(!terminating, NUTAG_USE_DIALOG(1)),
261 262 263
		     TAG_NEXT(tags));
  sip = sip_object(msg);

264 265
  if (sip) {
    du->du_terminating = terminating;
266

267 268 269 270
    if (du->du_msg)
      msg_destroy(du->du_msg);
    du->du_msg = msg_ref_create(cr->cr_msg);

271 272
    if (sip->sip_contact)
      register_usage_set_contact(ru, sip->sip_contact);
273

274 275 276 277 278
    if (!ru->ru_rcontact) {
      register_usage_set_contact_by_aor(ru, sip->sip_to->a_url,
					nh->nh_nua->nua_registrations);
      /* Try first time without contact if we are not natifying */
      ru->ru_add_contact = !NH_PGET(nh, natify);
279 280 281 282 283 284 285
    }

    if (terminating)
      /* Add Expires: 0 and remove expire parameter from contacts */
      unregister_expires_contacts(msg, sip);

    cr->cr_orq =
286 287 288
      nta_outgoing_mcreate(nua->nua_nta,
			   process_response_to_register, nh, NULL,
			   msg,
289
			   TAG_IF(ru->ru_add_contact,
290
				  SIPTAG_CONTACT(ru->ru_rcontact)),
291 292 293 294 295
			   TAG_IF(ru->ru_add_contact,
				  SIPTAG_CONTACT(ru->ru_previous)),
			   SIPTAG_END(),
			   TAG_IF(terminating, NTATAG_SIGCOMP_CLOSE(1)),
			   TAG_IF(!terminating, NTATAG_COMP("sigcomp")),
296
			   TAG_NEXT(tags));
297 298 299

    if (cr->cr_orq)
      ru->ru_registering = 1;
300
  }
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317

  if (!cr->cr_orq) {
    msg_destroy(msg);
    msg_destroy(cr->cr_msg), cr->cr_msg = NULL;
    return UA_EVENT1(e, NUA_500_ERROR);
  }

  cr->cr_usage = du;

  return cr->cr_event = e;
}

static void
restart_register(nua_handle_t *nh, tagi_t *tags)
{
  struct nua_client_request *cr = nh->nh_cr;
  msg_t *msg;
318 319 320
  nua_dialog_usage_t *du = cr->cr_usage;
  struct register_usage *ru = nua_dialog_usage_private(du);
  int unregistering = du && du->du_terminating;
321
  sip_contact_t *contact = NULL, *previous = NULL;
322 323 324 325 326 327 328

  cr->cr_restart = NULL;

  if (!cr->cr_msg)
    return;

  msg = nua_creq_msg(nh->nh_nua, nh, cr, 1,
329 330 331 332 333 334 335 336
		     SIP_METHOD_UNKNOWN,
		     TAG_NEXT(tags));

  if (!msg)
    return;			/* Uh-oh */

  if (unregistering)
    unregister_expires_contacts(msg, sip_object(msg));
337

338
  if (ru) {
339
    if (ru->ru_add_contact) {
340
      contact = ru->ru_rcontact;
341 342 343 344
      if (ru->ru_previous && ru->ru_previous->m_expires)
	previous = ru->ru_previous;
    }
  }
345

346 347 348 349 350
  cr->cr_orq = nta_outgoing_mcreate(nh->nh_nua->nua_nta,
				    process_response_to_register, nh, NULL,
				    msg,
				    SIPTAG_CONTACT(contact),
				    SIPTAG_CONTACT(previous),
351 352
				    SIPTAG_END(), TAG_NEXT(tags));

353 354 355 356
  if (cr->cr_orq) {
    ru->ru_registering = 1;
  }
  else
357 358 359 360 361 362 363 364 365 366 367
    msg_destroy(msg);
}

static
int process_response_to_register(nua_handle_t *nh,
				 nta_outgoing_t *orq,
				 sip_t const *sip)
{
  struct nua_client_request *cr = nh->nh_cr;
  nua_dialog_usage_t *du = cr->cr_usage;
  struct register_usage *ru = nua_dialog_usage_private(du);
368 369 370 371 372 373 374 375 376 377 378 379
  int status;
  char const *phrase;
  sip_t *req = sip_object(cr->cr_msg);

  assert(sip);
  assert(du && du->du_class == nua_register_usage);
  status = sip->sip_status->st_status;
  phrase = sip->sip_status->st_phrase;

  if (status < 200 || !du)
    return nua_stack_process_response(nh, cr, orq, sip, TAG_END());

380 381
  nua_dialog_store_peer_info(nh, nh->nh_ds, sip);

382
  if (NH_PGET(nh, natify)) {
383 384 385
    int reregister;

    reregister = register_usage_check_for_nat(ru, orq, sip);
386 387 388 389

    if (reregister < 0)
      SET_STATUS2(500, nua_500_error);
    else if (reregister > 0) {
390 391
      if (nua_creq_check_restart(nh, cr, orq, sip, restart_register))
	return 0;
392

393
      if (reregister > 1) {
394
	/* We can try to reregister immediately */
395 396 397
	nua_creq_restart_with(nh, cr, orq, 100, "Updated Contact",
			      restart_register,
			      TAG_END());
398 399 400 401 402
      }
      else {
	nua_creq_save_restart(nh, cr, orq, 100, "Updated Contact",
			      restart_register);
      }
403

404 405 406
      return 0;
    }
  }
407

408 409 410 411 412 413
  if (status >= 300) {
    if (nua_creq_check_restart(nh, cr, orq, sip, restart_register))
      return 0;
    du->du_ready = 0;
  }
  else if (status < 300) {
414 415
    du->du_ready = 1;

416 417 418 419 420 421
    if (!du->du_terminating && sip->sip_contact)
      ru->ru_registered = ru->ru_registering;
    else
      ru->ru_registered = 0;

    if (ru->ru_registered) {
422 423 424 425
      sip_time_t now = sip_now(), delta, mindelta;
      sip_contact_t const *m, *m0;

      /** Search for lowest delta of SIP contacts in sip->sip_contact */
426
      mindelta = SIP_TIME_MAX;
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441

      for (m = sip->sip_contact; m; m = m->m_next) {
	if (m->m_url->url_type != url_sip)
	  continue;
	for (m0 = req->sip_contact; m0; m0 = m0->m_next)
	  if (url_cmp(m->m_url, m0->m_url) == 0) {
	    delta = sip_contact_expires(m, sip->sip_expires, sip->sip_date,
					3600, /* XXX */
					now);
	    if (delta > 0 && delta < mindelta)
	      mindelta = delta;
	    break;
	  }
      }

442 443 444
      if (mindelta == SIP_TIME_MAX)
	mindelta = 3600;

445 446
      nua_dialog_usage_set_refresh(du, mindelta);
      du->du_pending = refresh_register;
447 448 449 450 451 452 453 454 455 456 457
    }

    if (!du->du_terminating) {
#if HAVE_SIGCOMP
      struct sigcomp_compartment *cc;
      cc = nta_outgoing_compartment(orq);
      sigcomp_compartment_unref(ru->ru_compartment);
      ru->ru_compartment = cc;
#endif
    }
  }
458

459
  /*  RFC 3608 Section 6.1 Procedures at the UA
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474

   The UA performs a registration as usual.  The REGISTER response may
   contain a Service-Route header field.  If so, the UA MAY store the
   value of the Service-Route header field in an association with the
   address-of-record for which the REGISTER transaction had registered a
   contact.  If the UA supports multiple addresses-of-record, it may be
   able to store multiple service routes, one per address-of-record.  If
   the UA refreshes the registration, the stored value of the Service-
   Route is updated according to the Service-Route header field of the
   latest 200 class response.  If there is no Service-Route header field
   in the response, the UA clears any service route for that address-
   of-record previously stored by the UA.  If the re-registration
   request is refused or if an existing registration expires and the UA
   chooses not to re-register, the UA SHOULD discard any stored service
   route for that address-of-record.
475

476 477 478 479
  */
  if (!du->du_terminating && status < 300) {
    su_free(nh->nh_home, ru->ru_route);
    ru->ru_route = sip_route_dup(nh->nh_home, sip->sip_service_route);
480 481
  }
  else {
482 483 484
    su_free(nh->nh_home, ru->ru_route);
    ru->ru_route = NULL;
  }
485

486 487 488 489 490
  /* RFC 3327 */
  /* We are mainly interested in the last part of the Path header */
  if (!du->du_terminating && status < 300) {
    sip_path_t *path = sip->sip_path;

491
    while (path && path->r_next)
492 493 494 495 496 497 498 499 500
      path = path->r_next;

    if (!ru->ru_path || !path ||
	url_cmp_all(ru->ru_path->r_url, path->r_url)) {
      su_free(nh->nh_home, ru->ru_path);
      ru->ru_path = sip_path_dup(nh->nh_home, path);
    }
  }

501 502 503 504 505 506 507
  if (!du->du_terminating && status < 300) {
    if (!ru->ru_prev) {
      /* Add to the list of registrations */
      if ((ru->ru_next = nh->nh_nua->nua_registrations))
	ru->ru_next->ru_prev = &ru->ru_next;
      ru->ru_prev = &nh->nh_nua->nua_registrations;
      nh->nh_nua->nua_registrations = ru;
508 509 510
    }
  }

511
  if (!du->du_terminating && status < 300 && ru->ru_nat_detected)
512
    register_usage_start_keepalive(ru, 15, orq);
513
  else
514
    register_usage_stop_keepalive(ru);
515

516 517 518
  return nua_stack_process_response(nh, cr, orq, sip, TAG_END());
}

519
void
520 521 522 523
refresh_register(nua_handle_t *nh, nua_dialog_usage_t *du, sip_time_t now)
{
  nua_t *nua = nh->nh_nua;
  nua_client_request_t *cr = nh->nh_cr;
524
  register_usage *ru = nua_dialog_usage_private(du);
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
  nua_event_t e;
  msg_t *msg;
  sip_t *sip;

  if (cr->cr_msg) {
    /* Delay of 5 .. 15 seconds */
    nua_dialog_usage_set_refresh(du, 5 + (unsigned)random() % 11U);
    du->du_pending = refresh_register;
    return;
  }

  if (now > 0)
    e = nua_r_register;
  else
    e = nua_r_destroy, du->du_terminating = 1;

541 542
  register_usage_stop_keepalive(ru);

543 544 545 546 547 548 549 550
  cr->cr_msg = msg_ref_create(du->du_msg);
  msg = nua_creq_msg(nua, nh, cr, 1,
		     SIP_METHOD_REGISTER,
		     NUTAG_USE_DIALOG(1),
		     TAG_END());
  sip = sip_object(msg);

  if (sip) {
551
    int unregistering = now == 0;
552
    sip_contact_t *contact, *previous;
553 554 555 556

    if (unregistering)
      unregister_expires_contacts(msg, sip);

557 558 559 560 561 562 563 564
    if (ru) {
      if (ru->ru_add_contact) {
	contact = ru->ru_rcontact;
	if (ru->ru_previous && ru->ru_previous->m_expires)
	  previous = ru->ru_previous;
      }
    }

565 566 567
    cr->cr_orq = nta_outgoing_mcreate(nua->nua_nta,
				      process_response_to_register, nh, NULL,
				      msg,
568 569
				      SIPTAG_CONTACT(contact),
				      SIPTAG_CONTACT(previous),
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
				      SIPTAG_END(), TAG_NEXT(NULL));
  }

  if (!cr->cr_orq) {
    if (du->du_terminating)
      nua_dialog_usage_remove(nh, nh->nh_ds, du);
    msg_destroy(msg);
    msg_destroy(cr->cr_msg);
    UA_EVENT2(e, NUA_500_ERROR, TAG_END());
    return;
  }

  cr->cr_usage = du;
  cr->cr_event = e;
}
585

586
/* ---------------------------------------------------------------------- */
587
/* Register usage interface */
588

589
static void nua_stack_tport_update(nua_t *nua, nta_agent_t *nta);
590

591 592 593 594 595 596
int
nua_stack_registrations_init(nua_t *nua)
{
  /* Create initial identities: peer-to-peer, public, sips */
  sip_via_t const *v;
  nua_handle_t *dnh = nua->nua_dhandle;
597

598 599 600 601
  v = nta_agent_public_via(nua->nua_nta);
  if (v) {
    register_usages_from_via(&nua->nua_registrations, dnh, v, 1);
  }
602

603 604 605
  v = nta_agent_via(nua->nua_nta);
  if (v) {
    register_usages_from_via(&nua->nua_registrations, dnh, v, 0);
606
  }
607 608
  else {
    sip_via_t v[2];
609

610 611 612 613 614 615
    sip_via_init(v)->v_next = v + 1;
    v[0].v_protocol = sip_transport_udp;
    v[0].v_host = "addr.is.invalid.";
    sip_via_init(v + 1);
    v[1].v_protocol = sip_transport_tcp;
    v[1].v_host = "addr.is.invalid.";
616

617
    register_usages_from_via(&nua->nua_registrations, dnh, v, 0);
618 619
  }

620 621
  nta_agent_bind_tport_update(nua->nua_nta, nua, 
			      nua_stack_tport_update);
622

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
  return 0;
}

static
void nua_stack_tport_update(nua_t *nua, nta_agent_t *nta)
{
}

sip_contact_t const *nua_contact_by_aor(nua_t *nua,
					url_t const *aor,
					int only_default)
{
  register_usage *ru = nua->nua_registrations;

  ru = register_usage_by_aor(ru, aor, only_default);

  return register_usage_contact(ru);
}

/** Return a string descibing our features. */
static
char *nua_stack_register_features(nua_handle_t *nh)
{
  char *retval;
  su_strlst_t *l = su_strlst_create(NULL);
  su_home_t *home = su_strlst_home(l);

  if (!l)
    return NULL;

  if (NH_PGET(nh, instance))
    su_slprintf(l, ";+sip.instance=\"<%s>\"", NH_PGET(nh, instance));

  if (NH_PGET(nh, callee_caps)) {
    sip_allow_t const *allow = NH_PGET(nh, allow);

    if (allow) {
      su_strlst_append(l, ";methods=\"");
      if (allow->k_items) {
	int i;
	for (i = 0; allow->k_items[i]; i++) {
	  su_strlst_append(l, allow->k_items[i]);
	  if (allow->k_items[i + 1])
	    su_strlst_append(l, ",");
	}
      }
      su_strlst_append(l, "\"");
    }

    if (nh->nh_soa) {
      char **media = soa_media_features(nh->nh_soa, 0, home);

      while (*media) {
	su_strlst_append(l, ";");
	su_strlst_append(l, *media++);
      }
    }
  }

  retval = su_strlst_join(l, nh->nh_home, "");

  su_strlst_destroy(l);

  return retval;
}

/** Remove (possible non-zero) "expires" parameters from contacts and extra
 *  contacts, add Expire: 0.
 */
static
void unregister_expires_contacts(msg_t *msg, sip_t *sip)
{
  sip_contact_t *m;
  int unregister_all;

  /* Remove payload */
  while (sip->sip_payload)
    sip_header_remove(msg, sip, (sip_header_t *)sip->sip_payload);
  while (sip->sip_content_type)
    sip_header_remove(msg, sip, (sip_header_t *)sip->sip_content_type);

  for (m = sip->sip_contact; m; m = m->m_next) {
    if (m->m_url->url_type == url_any)
      break;
    msg_header_remove_param(m->m_common, "expires");
#if 0
    msg_header_add_param(msg_home(msg), m->m_common, "expires=0");
#endif
  }

  unregister_all = m && (m != sip->sip_contact || m->m_next);

  sip_add_tl(msg, sip,
	     /* Remove existing contacts */
	     TAG_IF(unregister_all, SIPTAG_CONTACT(NONE)),
	     /* Add '*' contact: 0 */
	     TAG_IF(unregister_all, SIPTAG_CONTACT_STR("*")),
	     SIPTAG_EXPIRES_STR("0"),
	     TAG_END());
}


/** Callback from register_usage */
static int nua_stack_register_status(nua_handle_t *nh, register_usage *ru,
				     int status, char const *phrase,
				     tag_type_t tag, tag_value_t value, ...)
{
  ta_list ta;

  ta_start(ta, tag, value);

  nua_stack_event(nh->nh_nua, nh, NULL, 
		  nua_i_outbound, status, phrase, 
		  ta_tags(ta));

  ta_end(ta);

  return 0;
}

/** Callback from register_usage */
static int nua_stack_register_failed(nua_handle_t *nh, register_usage *ru,
				     int status, char const *phrase,
				     tag_type_t tag, tag_value_t value, ...)
{
  ta_list ta;
  ta_start(ta, tag, value);

  nua_stack_event(nh->nh_nua, nh, NULL, 
		  nua_i_outbound, status, phrase, 
		  ta_tags(ta));

  ta_end(ta);

  return 0;
}

/* ====================================================================== */
/* Register-usage side */

static
int register_usage_nat_detect(register_usage *ru, sip_via_t const *v);

/* ---------------------------------------------------------------------- */

/** Check if there is a NAT between us and registrar */
int register_usage_check_for_nat(struct register_usage *ru,
				 nta_outgoing_t *orq,
				 sip_t const *sip)
{
  sip_via_t *v = sip->sip_via;
  int binding_changed;
  sip_contact_t *m = ru->ru_rcontact;

#if 0
  if (host_is_domain(v->v_host)) {
    /*
     * If we use domain name in Via, we assume that application
     * knows something we don't.
     * Just use ordinary contact unless domain name ends with ".invalid"
     */
    char const *invalid = strcasestr(v->v_host, ".invalid");

    if (invalid)
      invalid += (sizeof ".invalid") - 1;
    if (invalid && invalid[0] == '.') /* ... or .invalid. */
      invalid++;

    if (!invalid || invalid[0] != '\0') {
      if (!ru->ru_rcontact)
	...
      if (!ru->ru_rcontact)
	return -1;
      return 0;
    }
  }
#endif

  binding_changed = register_usage_nat_detect(ru, v);

  /* Contact was set by application, do not change it */
  if (ru->ru_by_application)
    return 0;

  if (!ru->ru_nat_detected) {
    if (ru->ru_add_contact)
      return 0;
    ru->ru_add_contact = 1;
    return 2;
  }

  /* We have detected NAT. Now, what to do?
   * 1) do nothing - register as usual and let proxy take care of it?
   * 2) try to detect our public nat binding and use it
   * 2A) use public vias from nta generated by STUN or UPnP
   * 2B) use SIP Via header
   */

  /* Do we have to ask for reregistration */
  if (!m || binding_changed > 1) {
    if (ru->ru_stun) {
      /* Use STUN? */
      return 1;
    }
    else if (ru->ru_upnp) {
      /* Use UPnP */
829 830 831 832 833 834 835 836 837 838 839 840 841 842
      return 1;
    }
    else {
      if (register_usage_contacts_from_via(ru, sip->sip_via, NULL) < 0)
	return -1;
      ru->ru_add_contact = 1;
    }

    return 1;
  }

  return 0;
}

843 844 845 846 847 848 849 850
/** Based on "received" and possible "rport" parameters, check and update
 *  our NAT status.
 *
 * @retval 2 change in public NAT binding detected
 * @retval 1 NAT binding detected
 * @retval 0 no NAT binding detected
 * @retval -1 an error occurred
 */
851
static
852 853
int register_usage_nat_detect(register_usage *ru,
			      sip_via_t const *v)
854
{
855 856 857 858 859 860 861 862 863 864 865 866 867 868
  int one = 1;
  char const *received, *rport;
  char *nat_detected, *nat_port;
  char *new_detected, *new_port;
  su_home_t *home;

  if (!ru || !v)
    return -1;

  received = v->v_received;
  if (!received)
    return 0;

  rport = sip_via_port(v, &one); assert(rport);
869

870 871 872 873 874
  nat_detected = ru->ru_nat_detected;
  nat_port = ru->ru_nat_port;

  if (nat_detected && strcasecmp(received, nat_detected) == 0 &&
      nat_port && strcasecmp(rport, nat_port) == 0)
875
    return 1;
876 877 878 879 880 881

  if (!nat_detected) {
    SU_DEBUG_1(("register_usage: detected NAT: %s != %s\n",
		v->v_host, received));
    if (ru->ru_ro && ru->ru_ro->ro_status)
      ru->ru_ro->ro_status(ru->ru_owner, ru, 101, "NAT detected", TAG_END());
882
  }
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
  else {
    SU_DEBUG_1(("register_usage: NAT binding changed: "
		"[%s]:%s != [%s]:%s\n",
		nat_detected, nat_port, received, rport));
    if (ru->ru_ro && ru->ru_ro->ro_status)
      ru->ru_ro->ro_status(ru->ru_owner, ru, 102, "NAT binding changed", TAG_END());
  }

  /* Save our nat binding */

  home = (su_home_t *)ru->ru_owner;

  new_detected = su_strdup(home, received);
  new_port = su_strdup(home, rport);

  if (!new_detected || !new_port) {
    su_free(home, new_detected);
    su_free(home, new_port);
    return -1;
  }

  ru->ru_nat_detected = new_detected;
  ru->ru_nat_port = new_port;

  su_free(home, nat_detected);
  su_free(home, nat_port);

  return 2;
911
}
912

913
/* ---------------------------------------------------------------------- */
914

915 916
static int create_keepalive_message(struct register_usage *ru,
				    sip_t const *register_request);
917

918
static int keepalive_options(register_usage *ru);
919
static int keepalive_options_with_registration_probe(register_usage *ru);
920

921 922 923
static int response_to_keepalive_options(nua_owner_t *ru_casted_as_owner,
					 nta_outgoing_t *orq,
					 sip_t const *sip);
924

925 926 927
static void keepalive_timer(su_root_magic_t *root_magic,
			    su_timer_t *t,
			    su_timer_arg_t *ru_as_timer_arg);
928

929
void register_usage_start_keepalive(struct register_usage *ru,
930 931 932 933 934
				    unsigned interval,
				    nta_outgoing_t *register_transaction)
{
  if (ru->ru_kalt)
    su_timer_destroy(ru->ru_kalt), ru->ru_kalt = NULL;
935

936
  if (interval)
937 938
    ru->ru_kalt = su_timer_create(su_root_task(ru->ru_root),
				  /* 1000 * */ 100 * interval);
939

940 941 942
  ru->ru_keepalive = interval;

  if (!ru->ru_validated && ru->ru_sipstun && 0) {
943 944 945 946 947 948 949 950 951
    /* XXX */
  }
  else {
    if (register_transaction) {
      msg_t *msg = nta_outgoing_getrequest(register_transaction);
      sip_t const *register_request = sip_object(msg);
      create_keepalive_message(ru, register_request);
      msg_destroy(msg);
    }
952

953
    keepalive_options(ru);
954
  }
955 956 957 958
}

void register_usage_stop_keepalive(struct register_usage *ru)
{
959 960 961 962 963 964 965
  ru->ru_keepalive = 0;

  if (ru->ru_kalt)
    su_timer_destroy(ru->ru_kalt), ru->ru_kalt = NULL;

  if (ru->ru_kalo)
    nta_outgoing_destroy(ru->ru_kalo), ru->ru_kalo = NULL;
966 967
}

968
/** Create a message template for keepalive. */
969 970 971 972 973 974 975 976
static int create_keepalive_message(struct register_usage *ru,
				    sip_t const *regsip)
{
  msg_t *msg = nta_msg_create(ru->ru_nta, MSG_FLG_COMPACT), *previous;
  sip_t *osip = sip_object(msg);

  assert(regsip); assert(regsip->sip_request);

977
  if (
978
      sip_add_tl(msg, osip,
979 980
		 /* Duplicate essential headers from REGISTER request: 
		    From/To, Route */
981 982
		 SIPTAG_TO(regsip->sip_to),
		 SIPTAG_FROM(regsip->sip_from),
983 984 985 986
		 /* XXX - we should only use loose routing here */
		 /* XXX - if we used strict routing,
		    the route header/request_uri must be restored
		 */
987
		 SIPTAG_ROUTE(regsip->sip_route),
988
		 /* Add Max-Forwards 0 */
989
		 SIPTAG_MAX_FORWARDS_STR("0"),
990 991
		 SIPTAG_SUBJECT_STR("KEEPALIVE"),
		 SIPTAG_CALL_ID_STR(ru->ru_cookie),
992 993 994 995
		 TAG_END()) < 0 ||
      /* Create request-line, Call-ID, CSeq */
      nta_msg_request_complete(msg,
			       nta_default_leg(ru->ru_nta),
996
			       SIP_METHOD_OPTIONS,
997 998 999 1000 1001 1002 1003 1004 1005
			       (void *)regsip->sip_request->rq_url) < 0 ||
      msg_serialize(msg, (void *)osip) < 0 ||
      msg_prepare(msg) < 0)
    return msg_destroy(msg), -1;

  previous = ru->ru_kalmsg;
  ru->ru_kalmsg = msg;
  msg_destroy(previous);

1006 1007 1008
  return 0;
}

1009 1010 1011
static int keepalive_options(register_usage *ru)
{
  msg_t *req;
1012

1013 1014 1015
  if (ru->ru_kalo)
    return 0;

1016 1017 1018
  if (ru->ru_registered && !ru->ru_validated)
    return keepalive_options_with_registration_probe(ru);

1019 1020 1021 1022
  req = msg_copy(ru->ru_kalmsg);
  if (!req)
    return -1;

1023
  if (nta_msg_request_complete(req, nta_default_leg(ru->ru_nta),
1024 1025 1026
			       SIP_METHOD_UNKNOWN, NULL) < 0)
    return msg_destroy(req), -1;

1027 1028
  ru->ru_kalo = nta_outgoing_mcreate(ru->ru_nta,
				     response_to_keepalive_options,
1029 1030 1031 1032 1033 1034 1035
				     (nua_owner_t *)ru,
				     NULL,
				     req,
				     TAG_END());

  if (!ru->ru_kalo)
    return msg_destroy(req), -1;
1036

1037 1038 1039 1040
  return 0;
}

static int response_to_keepalive_options(nua_owner_t *ru_casted_as_owner,
1041 1042
					 nta_outgoing_t *orq,
					 sip_t const *sip)
1043
{
1044
  register_usage *ru = (register_usage *)ru_casted_as_owner;
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
  int status = 408;
  int binding_check;

  if (sip && sip->sip_status)
    status = sip->sip_status->st_status;

  if (status == 100) {
    /* This probably means that we are in trouble. whattodo, whattodo */
  }

  if (status < 200)
    return 0;

  if (orq == ru->ru_kalo)
    ru->ru_kalo = NULL;
  nta_outgoing_destroy(orq);

  if (status == 408) {
    SU_DEBUG_1(("register_usage(%p): keepalive timeout\n", ru));
    /* XXX - do something about it! */
    return 0;
  }

  binding_check = register_usage_nat_detect(ru, sip->sip_via);

  if (binding_check > 1) {
    /* Bindings have changed */
    /* XXX - do something about it! */
    if (register_usage_contacts_from_via(ru, sip->sip_via, NULL) == 0) {
      /* re-REGISTER */
      nua_dialog_usage_refresh(ru->ru_owner, nua_dialog_usage_public(ru), 1); 
      return 0;
    }
  }

  if (binding_check <= 1 && status < 300 && ru->ru_registered) {
    if (!ru->ru_validated)
      SU_DEBUG_1(("register_usage(%p): validated contact "
		  URL_PRINT_FORMAT "\n",
		  ru, URL_PRINT_ARGS(ru->ru_rcontact->m_url)));
    ru->ru_validated = ru->ru_once_validated = 1;
  }
1087 1088 1089 1090

  su_timer_set(ru->ru_kalt, keepalive_timer, ru);

  return 0;
1091 1092
}

1093 1094 1095
static void keepalive_timer(su_root_magic_t *root_magic,
			    su_timer_t *t,
			    su_timer_arg_t *ru_casted_as_timer_arg)
1096
{
1097 1098 1099
  register_usage *ru = (register_usage *)ru_casted_as_timer_arg;

  (void)root_magic;
1100

1101 1102
  if (keepalive_options(ru) < 0)
    su_timer_set(t, keepalive_timer, ru_casted_as_timer_arg);	/* XXX */
1103 1104
}

1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184

/** Send a keepalive OPTIONS that probes the registration */
static int keepalive_options_with_registration_probe(register_usage *ru)
{
  msg_t *req;
  sip_t *sip;
  void *request_uri;

  if (ru->ru_kalo)
    return 0;

  req = msg_copy(ru->ru_kalmsg);
  if (!req)
    return -1;

  sip = sip_object(req);
  request_uri = sip->sip_to->a_url;

  if (nta_msg_request_complete(req, nta_default_leg(ru->ru_nta),
			       SIP_METHOD_OPTIONS, request_uri) < 0)
    return msg_destroy(req), -1;

  if (ru->ru_features) {
    sip_accept_contact_t *ac;
    ac = sip_accept_contact_format(msg_home(req), "*;%s", ru->ru_features);
  }

  ru->ru_kalo = nta_outgoing_mcreate
    (ru->ru_nta,
     response_to_keepalive_options,
     (nua_owner_t *)ru,
     NULL,
     req,
     /* See RFC 3841 */
     SIPTAG_ACCEPT_STR(register_usage_content_type),
     SIPTAG_PROXY_REQUIRE_STR("pref"),
     SIPTAG_REQUEST_DISPOSITION_STR("proxy"),
     SIPTAG_SUBJECT_STR("REGISTRATION PROBE"),
     SIPTAG_MAX_FORWARDS(NONE),	/* Remove 0 used in ordinary keepalives */
     TAG_END());

  if (!ru->ru_kalo)
    return msg_destroy(req), -1;

  return 0;
}

/** Check if incoming OPTIONS is a registration probe */
int register_usage_check_accept(sip_accept_t const *accept)
{
  return
    accept &&
    accept->ac_type &&
    strcasecmp(accept->ac_type, register_usage_content_type) == 0;
}

/** Process incoming keepalive/validate OPTIONS */
int register_usage_process_options(struct register_usage *usages,
				   nta_incoming_t *irq,
				   sip_t const *sip)
{
  sip_call_id_t *i = sip->sip_call_id; assert(i);
  struct register_usage *ru;

  for (ru = usages; ru; ru = ru->ru_next) {
    if (strcmp(i->i_id, ru->ru_cookie) == 0)
      break;
  }

  if (!ru)
    return 481;			/* Call/Transaction does not exist */

  nta_incoming_treply(irq, SIP_200_OK,
		      SIPTAG_CONTENT_TYPE_STR(register_usage_content_type),
		      SIPTAG_PAYLOAD_STR(ru->ru_cookie),
		      TAG_END());

  return 501;
}

1185 1186
/* ---------------------------------------------------------------------- */

1187 1188 1189 1190 1191 1192 1193 1194
/** Create contacts for register usage.
 *
 * Each registration has two contacts: one suitable for registrations and
 * another that can be used in dialogs.
 */
int register_usage_contacts_from_via(register_usage *ru,
				     sip_via_t const *via,
				     sip_via_t const *pair)
1195
{
1196 1197 1198 1199 1200 1201
  su_home_t *home = (su_home_t *)ru->ru_owner;
  char *uri;
  sip_contact_t *rcontact, *dcontact;
  sip_contact_t *previous_rcontact, *previous_dcontact;
  char const *transport;
  sip_via_t *v, v0[1], *previous_via;
1202
  int contact_uri_changed;
1203

1204 1205
  if (!via)
    return -1;
1206

1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
  if (pair)
    /* Don't use protocol if we have both udp and tcp */
    transport = NULL;
  else
    transport = via->v_protocol;

  v = v0; *v0 = *via; v0->v_next = (sip_via_t *)pair;

  uri = sip_contact_string_from_via(NULL, via,