check_register.c 22.2 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
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) 2008 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 check_register.c
 *
 * @brief Check-driven tester for Sofia SIP User Agent library
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 *
 * @copyright (C) 2008 Nokia Corporation.
 */

#include "config.h"

36
#undef NDEBUG
Pekka Pessi's avatar
Pekka Pessi committed
37

38
#include "check_nua.h"
Pekka Pessi's avatar
Pekka Pessi committed
39 40 41 42 43 44

#include <sofia-sip/sip_status.h>
#include <sofia-sip/sip_header.h>
#include <sofia-sip/soa.h>
#include <sofia-sip/su_tagarg.h>
#include <sofia-sip/su_tag_io.h>
45
#include <sofia-sip/su_log.h>
Pekka Pessi's avatar
Pekka Pessi committed
46 47 48 49 50

#include <stdlib.h>
#include <string.h>
#include <assert.h>

51 52
SOFIAPUBVAR su_log_t tport_log[];

Pekka Pessi's avatar
Pekka Pessi committed
53 54 55 56
static nua_t *nua;

static void register_setup(void)
{
57
  nua = s2_nua_setup("register", TAG_END());
Pekka Pessi's avatar
Pekka Pessi committed
58 59
}

60 61 62 63 64 65 66 67 68 69 70 71 72
static void register_thread_setup(void)
{
  s2_nua_thread = 1;
  register_setup();
}

static void register_threadless_setup(void)
{
  s2_nua_thread = 1;
  register_setup();
}

static void pingpong_setup(void)
73
{
74 75
  nua = s2_nua_setup("register with pingpong",
		     TPTAG_PINGPONG(20000),
76 77
		     TPTAG_KEEPALIVE(10000),
		     TAG_END());
78
  tport_set_params(s2sip->tcp.tport, TPTAG_PONG2PING(1), TAG_END());
79 80
}

81 82 83 84 85 86 87 88 89 90 91
static void pingpong_thread_setup(void)
{
  s2_nua_thread = 1;
  pingpong_setup();
}

static void pingpong_threadless_setup(void)
{
  s2_nua_thread = 0;
  pingpong_setup();
}
92

Pekka Pessi's avatar
Pekka Pessi committed
93 94
static void register_teardown(void)
{
95
  s2_teardown_started("register");
Pekka Pessi's avatar
Pekka Pessi committed
96
  nua_shutdown(nua);
97
  fail_unless_event(nua_r_shutdown, 200);
Pekka Pessi's avatar
Pekka Pessi committed
98 99 100
  s2_nua_teardown();
}

101 102 103 104 105 106 107 108 109 110 111
static void add_register_fixtures(TCase *tc, int threading, int pingpong)
{
  void (*setup)(void);

  if (pingpong)
    setup = threading ? pingpong_thread_setup : pingpong_threadless_setup;
  else
    setup = threading ? register_thread_setup : register_threadless_setup;

  tcase_add_checked_fixture(tc, setup, register_teardown);
}
112

Pekka Pessi's avatar
Pekka Pessi committed
113 114
/* ---------------------------------------------------------------------- */

115
START_TEST(register_1_0_1)
Pekka Pessi's avatar
Pekka Pessi committed
116 117 118 119
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
120
  S2_CASE("1.0.1", "Failed Register", "REGISTER returned 403 response");
Pekka Pessi's avatar
Pekka Pessi committed
121 122 123

  nua_register(nh, TAG_END());

124
  fail_unless((m = s2_sip_wait_for_request(SIP_METHOD_REGISTER)) != NULL, NULL);
Pekka Pessi's avatar
Pekka Pessi committed
125

126
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
127 128
		SIP_403_FORBIDDEN,
		TAG_END());
129
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
130 131 132 133 134 135 136 137

  nua_handle_destroy(nh);

} END_TEST


START_TEST(register_1_1_1)
{
Pekka Pessi's avatar
Pekka Pessi committed
138
  S2_CASE("1.1.1", "Basic Register", "REGISTER returning 200 OK");
Pekka Pessi's avatar
Pekka Pessi committed
139 140 141 142 143 144 145 146 147 148 149 150 151

  s2_register_setup();

  s2_register_teardown();

} END_TEST


START_TEST(register_1_1_2)
{
  nua_handle_t *nh;
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
152
  S2_CASE("1.1.2", "Register with dual authentication",
Pekka Pessi's avatar
Pekka Pessi committed
153 154 155 156 157 158
	  "Register, authenticate");

  nh = nua_handle(nua, NULL, TAG_END());

  nua_register(nh, TAG_END());

159 160
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m);
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
161 162 163
		SIP_407_PROXY_AUTH_REQUIRED,
		SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
		TAG_END());
164
  s2_sip_free_message(m);
165
  fail_unless_event(nua_r_register, 407);
Pekka Pessi's avatar
Pekka Pessi committed
166 167 168

  nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());

169 170
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m);
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
171 172 173 174
		SIP_401_UNAUTHORIZED,
		SIPTAG_WWW_AUTHENTICATE_STR(s2_auth2_digest_str),
		SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
		TAG_END());
175
  s2_sip_free_message(m);
176
  fail_unless_event(nua_r_register, 401);
Pekka Pessi's avatar
Pekka Pessi committed
177 178 179

  nua_authenticate(nh, NUTAG_AUTH(s2_auth2_credentials), TAG_END());

180
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
181 182 183 184 185
  fail_if(!m);
  fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_proxy_authorization);
  s2_save_register(m);

186
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
187 188 189
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
		TAG_END());
190
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
191 192

  assert(s2->registration->contact != NULL);
193
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
194 195 196 197 198 199 200 201 202

  s2->registration->nh = nh;

  s2_register_teardown();

} END_TEST

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

203 204
static char const receive_natted[] = "received=4.255.255.9";
static char const receive_natted2[] = "received=4.255.255.10";
Pekka Pessi's avatar
Pekka Pessi committed
205 206

/* Return Via that looks very natted */
207
static sip_via_t *natted_via(struct message *m, const char *receive_natted)
Pekka Pessi's avatar
Pekka Pessi committed
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
{
  su_home_t *h;
  sip_via_t *via;

  h = msg_home(m->msg);
  via = sip_via_dup(h, m->sip->sip_via);
  msg_header_replace_param(h, via->v_common, receive_natted);

  if (via->v_protocol == sip_transport_udp)
    msg_header_replace_param(h, via->v_common, "rport=9");

  if (via->v_protocol == sip_transport_tcp && via->v_rport) {
    tp_name_t const *tpn = tport_name(m->tport);
    char *rport = su_sprintf(h, "rport=%s", tpn->tpn_port);
    msg_header_replace_param(h, via->v_common, rport);
  }

  return via;
}

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

START_TEST(register_1_2_1) {
  nua_handle_t *nh;
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
234
  S2_CASE("1.2.1", "Register behind NAT",
Pekka Pessi's avatar
Pekka Pessi committed
235 236 237 238 239 240
	  "Register through NAT, detect NAT, re-REGISTER");

  nh = nua_handle(nua, NULL, TAG_END());

  nua_register(nh, TAG_END());

241
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
242 243 244 245
  fail_if(!m);
  fail_if(!m->sip->sip_contact || m->sip->sip_contact->m_next);
  s2_save_register(m);

246
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
247 248
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
249
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
250
		TAG_END());
251
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
252 253

  assert(s2->registration->contact != NULL);
254
  fail_unless_event(nua_r_register, 100);
Pekka Pessi's avatar
Pekka Pessi committed
255

256
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
257 258 259 260
  fail_if(!m);
  fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next);
  s2_save_register(m);

261
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
262 263
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
264
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
265
		TAG_END());
266
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
267 268 269

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);
270
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289

  s2->registration->nh = nh;

  s2_register_teardown();

} END_TEST


static nua_handle_t *make_auth_natted_register(
  nua_handle_t *nh,
  tag_type_t tag, tag_value_t value, ...)
{
  struct message *m;

  ta_list ta;
  ta_start(ta, tag, value);
  nua_register(nh, ta_tags(ta));
  ta_end(ta);

290 291
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m);
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
292 293
		SIP_401_UNAUTHORIZED,
		SIPTAG_WWW_AUTHENTICATE_STR(s2_auth_digest_str),
294
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
295
		TAG_END());
296
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
297

298
  fail_unless_event(nua_r_register, 401);
Pekka Pessi's avatar
Pekka Pessi committed
299 300 301

  nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());

302
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
303 304
  fail_if(!m);
  fail_if(!m->sip->sip_authorization);
305 306 307 308
  /* should not unregister the previous contact
   * as it has not been successfully registered */
  fail_if(!m->sip->sip_contact);
  fail_if(m->sip->sip_contact->m_next);
Pekka Pessi's avatar
Pekka Pessi committed
309 310
  s2_save_register(m);

311
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
312 313
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
314
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
315
		TAG_END());
316
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
317 318

  assert(s2->registration->contact != NULL);
319
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
320 321 322 323 324 325 326 327

  return nh;
}

START_TEST(register_1_2_2_1)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());

Pekka Pessi's avatar
Pekka Pessi committed
328
  S2_CASE("1.2.2.1", "Register behind NAT",
Pekka Pessi's avatar
Pekka Pessi committed
329 330 331 332 333 334 335 336 337 338 339 340 341 342
	  "Authenticate, outbound activated");

  mark_point();
  make_auth_natted_register(nh, TAG_END());
  s2->registration->nh = nh;
  s2_register_teardown();
}
END_TEST

START_TEST(register_1_2_2_2)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
343
  S2_CASE("1.2.2.2", "Register behind NAT",
Pekka Pessi's avatar
Pekka Pessi committed
344 345 346 347 348 349 350 351 352 353
	  "Authenticate, outbound activated, "
	  "authenticate OPTIONS probe, "
	  "NAT binding change");

  mark_point();
  make_auth_natted_register(nh, TAG_END());
  s2->registration->nh = nh;

  mark_point();

354
  m = s2_sip_wait_for_request(SIP_METHOD_OPTIONS);
Pekka Pessi's avatar
Pekka Pessi committed
355
  fail_if(!m);
356
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
357
		SIP_407_PROXY_AUTH_REQUIRED,
358
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
359 360
		SIPTAG_PROXY_AUTHENTICATE_STR(s2_auth_digest_str),
		TAG_END());
361
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
362 363
  mark_point();

364
  m = s2_sip_wait_for_request(SIP_METHOD_OPTIONS);
Pekka Pessi's avatar
Pekka Pessi committed
365
  fail_if(!m); fail_if(!m->sip->sip_proxy_authorization);
366
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
367
		SIP_200_OK,
368
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
369
		TAG_END());
370
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
371

372 373
  su_root_step(s2base->root, 20); su_root_step(s2base->root, 20);
  s2_nua_fast_forward(120, s2base->root);	  /* Default keepalive interval */
Pekka Pessi's avatar
Pekka Pessi committed
374 375
  mark_point();

376 377
  m = s2_sip_wait_for_request(SIP_METHOD_OPTIONS);
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
378
		SIP_200_OK,
379
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
380
		TAG_END());
381
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
382

383 384
  su_root_step(s2base->root, 20); su_root_step(s2base->root, 20);
  s2_nua_fast_forward(120, s2base->root);	  /* Default keepalive interval */
Pekka Pessi's avatar
Pekka Pessi committed
385 386
  mark_point();

387 388
  m = s2_sip_wait_for_request(SIP_METHOD_OPTIONS);
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
389
		SIP_200_OK,
390
		SIPTAG_VIA(natted_via(m, receive_natted2)),
Pekka Pessi's avatar
Pekka Pessi committed
391
		TAG_END());
392
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
393

394
  fail_unless_event(nua_i_outbound, 0);
Pekka Pessi's avatar
Pekka Pessi committed
395

396
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
397 398 399 400
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next);
  s2_save_register(m);

401
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
402 403
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
404
		SIPTAG_VIA(natted_via(m, receive_natted2)),
Pekka Pessi's avatar
Pekka Pessi committed
405
		TAG_END());
406
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
407

408
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
409 410 411 412 413 414 415 416 417 418 419 420 421 422

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);

  s2_register_teardown();

} END_TEST


START_TEST(register_1_2_2_3)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
423
  S2_CASE("1.2.2.3", "Register behind NAT",
Pekka Pessi's avatar
Pekka Pessi committed
424 425 426 427
	  "Authenticate, outbound activated, "
	  "detect NAT binding change when re-REGISTERing");

  mark_point();
428

Pekka Pessi's avatar
Pekka Pessi committed
429
  make_auth_natted_register(nh,
430
			    NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
Pekka Pessi's avatar
Pekka Pessi committed
431 432 433
			    TAG_END());
  s2->registration->nh = nh;

434
  s2_nua_fast_forward(3600, s2base->root);
Pekka Pessi's avatar
Pekka Pessi committed
435 436
  mark_point();

437
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
438 439 440
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  s2_save_register(m);

441
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
442 443
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
444
		SIPTAG_VIA(natted_via(m, receive_natted2)),
Pekka Pessi's avatar
Pekka Pessi committed
445
		TAG_END());
446
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
447

448
  fail_unless_event(nua_r_register, 100);
Pekka Pessi's avatar
Pekka Pessi committed
449

450
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
451 452 453 454
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next);
  s2_save_register(m);

455
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
456 457
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
458
		SIPTAG_VIA(natted_via(m, receive_natted2)),
Pekka Pessi's avatar
Pekka Pessi committed
459
		TAG_END());
460
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
461 462 463 464

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);

465
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
466 467 468 469 470 471 472 473 474 475

  s2_register_teardown();

} END_TEST


START_TEST(register_1_2_3) {
  nua_handle_t *nh;
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
476
  S2_CASE("1.2.3", "Register behind NAT",
Pekka Pessi's avatar
Pekka Pessi committed
477 478 479 480 481 482 483
	  "Outbound activated by error response");

  nh = nua_handle(nua, NULL, TAG_END());
  nua_register(nh, TAG_END());

  mark_point();

484
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
485 486 487
  fail_if(!m);
  fail_if(!m->sip->sip_contact || m->sip->sip_contact->m_next);

488
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
489
		400, "Bad Contact",
490
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
491
		TAG_END());
492
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
493

494
  fail_unless_event(nua_r_register, 100);
Pekka Pessi's avatar
Pekka Pessi committed
495

496
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
497 498 499
  fail_if(!m);
  s2_save_register(m);

500
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
501 502
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
503
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
504
		TAG_END());
505
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
506 507 508

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);
509
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524

  s2->registration->nh = nh;

  s2_register_teardown();

} END_TEST


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

START_TEST(register_1_3_1)
{
  nua_handle_t *nh;
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
525
  S2_CASE("1.3.1", "Register over TCP via NAT",
Pekka Pessi's avatar
Pekka Pessi committed
526 527 528 529
	  "REGISTER via TCP, detect NTA, re-REGISTER");

  nh = nua_handle(nua, NULL, TAG_END());

530
  nua_register(nh, NUTAG_PROXY(s2sip->tcp.contact->m_url), TAG_END());
Pekka Pessi's avatar
Pekka Pessi committed
531

532
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
533 534 535 536
  fail_if(!m); fail_if(!m->sip->sip_contact || m->sip->sip_contact->m_next);
  fail_if(!tport_is_tcp(m->tport));
  s2_save_register(m);

537
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
538 539
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
540
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
541
		TAG_END());
542
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
543 544

  assert(s2->registration->contact != NULL);
545
  fail_unless_event(nua_r_register, 100);
Pekka Pessi's avatar
Pekka Pessi committed
546

547
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
548 549 550 551
  fail_if(!m);
  fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next);
  s2_save_register(m);

552
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
553 554
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
555
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
556
		TAG_END());
557
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
558 559 560 561 562

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);
  fail_unless(
    url_has_param(s2->registration->contact->m_url, "transport=tcp"));
563
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
564 565 566 567 568 569 570 571 572 573 574 575

  s2->registration->nh = nh;

  s2_register_teardown();

} END_TEST


START_TEST(register_1_3_2_1)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());

Pekka Pessi's avatar
Pekka Pessi committed
576
  S2_CASE("1.3.2.1", "Register behind NAT",
Pekka Pessi's avatar
Pekka Pessi committed
577 578 579 580
	  "Authenticate, outbound activated");

  mark_point();
  s2->registration->nh = nh;
581
  make_auth_natted_register(nh, NUTAG_PROXY(s2sip->tcp.contact->m_url), TAG_END());
Pekka Pessi's avatar
Pekka Pessi committed
582 583 584 585 586 587 588 589 590 591 592
  fail_if(!tport_is_tcp(s2->registration->tport));
  s2_register_teardown();
}
END_TEST


START_TEST(register_1_3_2_2)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());
  struct message *m;

Pekka Pessi's avatar
Pekka Pessi committed
593
  S2_CASE("1.3.2.2", "Register behind NAT with TCP",
Pekka Pessi's avatar
Pekka Pessi committed
594 595 596 597 598
	  "Detect NAT over TCP using rport. "
	  "Authenticate, detect NAT, "
	  "close TCP at server, wait for re-REGISTERs.");

  nua_set_params(nua, NTATAG_TCP_RPORT(1), TAG_END());
599
  fail_unless_event(nua_r_set_params, 200);
Pekka Pessi's avatar
Pekka Pessi committed
600 601 602 603

  mark_point();
  s2->registration->nh = nh;
  make_auth_natted_register(
604
    nh, NUTAG_PROXY(s2sip->tcp.contact->m_url),
Pekka Pessi's avatar
Pekka Pessi committed
605 606 607 608 609
    NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
    TAG_END());
  fail_if(!tport_is_tcp(s2->registration->tport));
  tport_shutdown(s2->registration->tport, 2);

610
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
611 612 613
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  s2_save_register(m);

614
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
615 616
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
617
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
618
		TAG_END());
619
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
620 621 622

  /* The "NAT binding" changed when new TCP connection is established */
  /* => NUA re-REGISTERs with newly detected contact */
623
  fail_unless_event(nua_r_register, 100);
Pekka Pessi's avatar
Pekka Pessi committed
624

625
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
Pekka Pessi's avatar
Pekka Pessi committed
626 627 628 629
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next);
  s2_save_register(m);

630
  s2_sip_respond_to(m, NULL,
Pekka Pessi's avatar
Pekka Pessi committed
631 632
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
633
		SIPTAG_VIA(natted_via(m, receive_natted)),
Pekka Pessi's avatar
Pekka Pessi committed
634
		TAG_END());
635
  s2_sip_free_message(m);
Pekka Pessi's avatar
Pekka Pessi committed
636

637
  fail_unless_event(nua_r_register, 200);
Pekka Pessi's avatar
Pekka Pessi committed
638 639 640 641 642 643 644 645

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);

  s2_register_teardown();
}
END_TEST

646
#if nomore
647 648 649 650 651 652
START_TEST(register_1_3_3_1)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());
  struct message *m;
  tport_t *tcp;

Pekka Pessi's avatar
Pekka Pessi committed
653
  S2_CASE("1.3.3.1", "Register behind NAT with UDP and TCP",
654 655 656
	  "Register with UDP, UDP time-outing, then w/ TCP using rport. ");

  nua_set_params(nua, NTATAG_TCP_RPORT(1), TAG_END());
657
  fail_unless_event(nua_r_set_params, 200);
658 659 660 661 662 663 664 665 666 667

  mark_point();
  s2->registration->nh = nh;

  nua_register(nh,
	       NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
	       TAG_END());

  /* NTA tries with UDP, we drop them */
  for (;;) {
668
    m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m);
669 670
    if (!tport_is_udp(m->tport)) /* Drop UDP */
      break;
671 672
    s2_sip_free_message(m);
    s2_nua_fast_forward(4, s2base->root);
673 674 675 676 677
  }

  tcp = tport_ref(m->tport);

  /* Respond to request over TCP */
678
  s2_sip_respond_to(m, NULL,
679 680
		SIP_401_UNAUTHORIZED,
		SIPTAG_WWW_AUTHENTICATE_STR(s2_auth_digest_str),
681
		SIPTAG_VIA(natted_via(m, receive_natted)),
682
		TAG_END());
683
  s2_sip_free_message(m);
684
  fail_unless_event(nua_r_register, 401);
685 686 687 688 689 690
  nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());

  /* Turn off pong */
  tport_set_params(tcp, TPTAG_PONG2PING(0), TAG_END());

  /* Now request over UDP ... registering TCP contact! */
691
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
692 693 694 695
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  s2_save_register(m);
  fail_unless(
    url_has_param(s2->registration->contact->m_url, "transport=tcp"));
696
  s2_sip_respond_to(m, NULL,
697 698
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
699
		SIPTAG_VIA(natted_via(m, receive_natted)),
700
		TAG_END());
701
  s2_sip_free_message(m);
702 703

  /* NUA detects oops... re-registers UDP */
704
  fail_unless_event(nua_r_register, 100);
705

706
  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
707 708 709 710
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next);
  s2_save_register(m);

711
  s2_sip_respond_to(m, NULL,
712 713
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
714
		SIPTAG_VIA(natted_via(m, receive_natted)),
715
		TAG_END());
716
  s2_sip_free_message(m);
717

718
  fail_unless_event(nua_r_register, 200);
719 720 721 722 723 724 725 726

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);

  /* Wait until ping-pong failure closes the TCP connection */
  {
    int i;
    for (i = 0; i < 5; i++) {
727 728 729 730
      su_root_step(s2base->root, 5);
      su_root_step(s2base->root, 5);
      su_root_step(s2base->root, 5);
      s2_nua_fast_forward(5, s2base->root);
731 732 733 734 735 736
    }
  }

  s2_register_teardown();
}
END_TEST
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 829 830 831 832 833 834 835 836 837 838 839
#endif

START_TEST(register_1_3_3_2)
{
  nua_handle_t *nh = nua_handle(nua, NULL, TAG_END());
  struct message *m;
  tport_t *tcp;
  int i;

  S2_CASE("1.3.3.2", "Register behind NAT with TCP",
	  "Register w/ TCP using rport, pingpong. ");

  nua_set_params(nua, NTATAG_TCP_RPORT(1), TAG_END());
  fail_unless_event(nua_r_set_params, 200);

  mark_point();
  s2->registration->nh = nh;

  nua_register(nh,
	       NUTAG_PROXY(s2sip->tcp.contact->m_url),
	       NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
	       TAG_END());

  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m);

  fail_unless(tport_is_tcp(m->tport));

  tcp = tport_ref(m->tport);

  /* Respond to request over TCP */
  s2_sip_respond_to(m, NULL,
		SIP_401_UNAUTHORIZED,
		SIPTAG_WWW_AUTHENTICATE_STR(s2_auth_digest_str),
		SIPTAG_VIA(natted_via(m, receive_natted)),
		TAG_END());
  s2_sip_free_message(m);
  fail_unless_event(nua_r_register, 401);
  nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());

  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact);
  s2_save_register(m);

  s2_sip_respond_to(m, NULL,
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
		SIPTAG_VIA(natted_via(m, receive_natted)),
		TAG_END());
  s2_sip_free_message(m);

  fail_unless_event(nua_r_register, 200);

  fail_unless(s2->registration->contact != NULL);
  fail_if(s2->registration->contact->m_next != NULL);

  /* Turn off pong */
  tport_set_params(tcp, TPTAG_PONG2PING(0), TAG_END());

  /* Wait until ping-pong failure closes the TCP connection */
  for (i = 0; i < 100; i++) {
    s2_nua_fast_forward(5, s2base->root);
    if (tport_is_closed(tcp))
      break;
  }

  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
  fail_unless(tport_is_tcp(m->tport));
  fail_unless(tcp != m->tport);
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact);
  s2_save_register(m);

  s2_sip_respond_to(m, NULL,
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
		SIPTAG_VIA(natted_via(m, receive_natted)),
		TAG_END());
  s2_sip_free_message(m);

  tport_unref(tcp);

  /* Contact changed */
  fail_unless_event(nua_r_register, 100);

  m = s2_sip_wait_for_request(SIP_METHOD_REGISTER);
  fail_if(!m); fail_if(!m->sip->sip_authorization);
  fail_if(!m->sip->sip_contact);
  fail_if(!m->sip->sip_contact->m_next);
  s2_save_register(m);

  s2_sip_respond_to(m, NULL,
		SIP_200_OK,
		SIPTAG_CONTACT(s2->registration->contact),
		SIPTAG_VIA(natted_via(m, receive_natted)),
		TAG_END());
  s2_sip_free_message(m);

  fail_unless_event(nua_r_register, 200);

  s2_register_teardown();
}
END_TEST
840

Pekka Pessi's avatar
Pekka Pessi committed
841 842
/* ---------------------------------------------------------------------- */

843
TCase *register_tcase(int threading)
Pekka Pessi's avatar
Pekka Pessi committed
844 845
{
  TCase *tc = tcase_create("1 - REGISTER");
846 847 848

  add_register_fixtures(tc, threading, 0);

Pekka Pessi's avatar
Pekka Pessi committed
849
  {
850
    tcase_add_test(tc, register_1_0_1);
Pekka Pessi's avatar
Pekka Pessi committed
851 852 853 854 855 856 857 858 859 860 861
    tcase_add_test(tc, register_1_1_1);
    tcase_add_test(tc, register_1_1_2);
    tcase_add_test(tc, register_1_2_1);
    tcase_add_test(tc, register_1_2_2_1);
    tcase_add_test(tc, register_1_2_2_2);
    tcase_add_test(tc, register_1_2_2_3);
    tcase_add_test(tc, register_1_2_3);
    tcase_add_test(tc, register_1_3_1);
    tcase_add_test(tc, register_1_3_2_1);
    tcase_add_test(tc, register_1_3_2_2);
  }
862
  tcase_set_timeout(tc, 10);
Pekka Pessi's avatar
Pekka Pessi committed
863 864 865
  return tc;
}

866
TCase *pingpong_tcase(int threading)
867
{
868 869 870 871
  TCase *tc = tcase_create("1 - REGISTER (with PingPong)");

  add_register_fixtures(tc, threading, 1);

872
  {
873
    tcase_add_test(tc, register_1_3_3_2);
874
  }
875

876
  tcase_set_timeout(tc, 10);
877 878 879
  return tc;
}

880
void check_register_cases(Suite *suite, int threading)
Pekka Pessi's avatar
Pekka Pessi committed
881
{
882 883
  suite_add_tcase(suite, register_tcase(threading));
  suite_add_tcase(suite, pingpong_tcase(threading));
Pekka Pessi's avatar
Pekka Pessi committed
884 885
}