1 /* srp-client.c 2 * 3 * Copyright (c) 2018-2023 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * SRP Client 18 * 19 * DNSServiceRegister API for SRP. See dns_sd.h for details on the API. 20 */ 21 22 #include <stdio.h> 23 #include <string.h> 24 #include <strings.h> 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <inttypes.h> 28 #include <errno.h> 29 #include "srp.h" 30 #ifdef SRP_TEST_SERVER 31 #undef DNSServiceRegister 32 #define DNSServiceRegister srp_client_register 33 #undef DNSServiceUpdateRecord 34 #define DNSServiceUpdateRecord srp_client_update_record 35 #undef DNSServiceRefDeallocate 36 #define DNSServiceRefDeallocate srp_client_ref_deallocate 37 #endif 38 #ifdef THREAD_DEVKIT_ADK 39 #include "../mDNSShared/dns_sd.h" 40 #else 41 #include <dns_sd.h> 42 #include <arpa/inet.h> 43 #endif 44 #include "srp-api.h" 45 #include "dns-msg.h" 46 #include "srp-crypto.h" 47 48 // By default, never wait longer than an hour to do another registration attempt. 49 #define DEFAULT_MAX_ATTEMPT_INTERVAL 1000 * 60 * 60 50 51 // Default retry interval is 15 seconds--three attempts. This is how long we will remain in the process of retrying 52 // an update on a particular server before we give up on that server. 53 54 #define DEFAULT_MAX_RETRY_INTERVAL 1000 * 15 55 56 // When we start talking to a particular server, we allow 2 seconds before the first retransmission 57 #define INITIAL_NEXT_RETRANSMISSION_TIME 2000 58 59 // When we fail to get through to any server, we will initially re-attempt contacting that server after 60 // this amount of time 61 #define INITIAL_NEXT_ATTEMPT_TIME 1000 * 2 * 60 62 63 typedef struct client_state client_state_t; 64 65 typedef struct service_addr service_addr_t; 66 struct service_addr { 67 service_addr_t *NULLABLE next; 68 dns_rr_t rr; 69 uint8_t port[2]; 70 }; 71 72 typedef struct _DNSServiceRef_t reg_state_t; 73 typedef struct update_context { 74 void *udp_context; 75 void *message; 76 client_state_t *NONNULL client; 77 service_addr_t *server; 78 size_t message_length; 79 uint32_t next_retransmission_time; 80 uint32_t next_attempt_time; 81 uint32_t lease_time; 82 uint32_t key_lease_time; 83 uint32_t serial; 84 uint32_t interface_serial; 85 bool notified; // Callers have been notified. 86 bool connected; // UDP context is connected. 87 bool removing; // We are removing the current registration(s) 88 } update_context_t; 89 90 struct _DNSServiceRef_t { 91 reg_state_t *NULLABLE next; 92 uint32_t serial; 93 DNSServiceFlags flags; 94 uint32_t interfaceIndex; 95 char *NULLABLE name; 96 char *NULLABLE regtype; 97 char *NULLABLE domain; 98 char *NULLABLE host; 99 int port; 100 uint16_t txtLen; 101 void *NULLABLE txtRecord; 102 DNSServiceRegisterReply callback; 103 bool succeeded; 104 bool called_back; 105 bool removing; 106 bool skip; 107 void *NULLABLE context; 108 }; 109 110 struct client_state { 111 client_state_t *next; 112 reg_state_t *registrations; 113 char *hostname; 114 int hostname_rename_number; // If we've had a naming conflict, this will be nonzero. 115 srp_hostname_conflict_callback_t hostname_conflict_callback; 116 srp_key_t *key; 117 void *os_context; 118 uint32_t lease_time; 119 uint32_t key_lease_time; 120 uint32_t srp_max_attempt_interval; 121 uint32_t registration_serial; 122 uint32_t srp_max_retry_interval; 123 service_addr_t stable_server; 124 bool srp_server_synced; 125 126 // Currently we only ever have one update in flight. If we decide we need to send another, 127 // we need to cancel the one we're currently doing. 128 update_context_t *active_update; 129 }; 130 131 // Implementation of SRP network entry points, which can be called by the network implementation on the 132 // hosting platform. 133 134 static bool network_state_changed = false; 135 static bool doing_refresh = false; 136 static service_addr_t *interfaces; 137 static service_addr_t *servers; 138 static service_addr_t *interface_refresh_state; 139 static service_addr_t *server_refresh_state; 140 static uint8_t no_port[2]; 141 static uint32_t interface_serial; 142 143 client_state_t *clients; 144 client_state_t *current_client; 145 bool zero_addresses = false; // for testing, used by srp-ioloop.c. 146 147 // Forward references 148 static int do_srp_update(client_state_t *client, bool definite, bool *did_something); 149 static void udp_response(void *v_update_context, void *v_message, size_t message_length); 150 151 static bool srp_is_network_active(void); 152 153 #define VALIDATE_IP_ADDR \ 154 if ((rrtype != dns_rrtype_a && rrtype != dns_rrtype_aaaa) || \ 155 (rrtype == dns_rrtype_a && rdlen != 4) || \ 156 (rrtype == dns_rrtype_aaaa && rdlen != 16)) { \ 157 return kDNSServiceErr_Invalid; \ 158 } 159 160 161 client_state_t * 162 srp_client_get_current(void) 163 { 164 return current_client; 165 } 166 167 void 168 srp_client_set_current(client_state_t *new_client) 169 { 170 current_client = new_client; 171 } 172 173 // Call this before calling anything else. Context will be passed back whenever the srp code 174 // calls any of the host functions. 175 int 176 srp_host_init(void *context) 177 { 178 client_state_t *new_client = calloc(1, sizeof(*new_client)); 179 if (new_client == NULL) { 180 return kDNSServiceErr_NoMemory; 181 } 182 new_client->os_context = context; 183 new_client->lease_time = 3600; // 1 hour for registration leases 184 new_client->key_lease_time = 604800; // 7 days for key leases 185 new_client->registration_serial = 1; 186 new_client->srp_max_attempt_interval = DEFAULT_MAX_ATTEMPT_INTERVAL; 187 new_client->srp_max_retry_interval = DEFAULT_MAX_RETRY_INTERVAL; 188 189 current_client = new_client; 190 new_client->next = clients; 191 clients = current_client; 192 return kDNSServiceErr_NoError; 193 } 194 195 int 196 srp_host_key_reset_for_client(client_state_t *client) 197 { 198 if (client->key != NULL) { 199 srp_keypair_free(client->key); 200 client->key = NULL; 201 } 202 return srp_reset_key("com.apple.srp-client.host-key", client->os_context); 203 } 204 205 int 206 srp_host_key_reset(void) 207 { 208 return srp_host_key_reset_for_client(current_client); 209 } 210 211 int 212 srp_set_lease_times(uint32_t new_lease_time, uint32_t new_key_lease_time) 213 { 214 current_client->lease_time = new_lease_time; 215 current_client->key_lease_time = new_key_lease_time; 216 return kDNSServiceErr_NoError; 217 } 218 219 static void 220 sync_from_stable_storage(update_context_t *update) 221 { 222 service_addr_t *server; 223 client_state_t *client = update->client; 224 if (!client->srp_server_synced) { 225 client->srp_server_synced = 226 srp_get_last_server(&client->stable_server.rr.type, (uint8_t *)&client->stable_server.rr.data, 227 sizeof(client->stable_server.rr.data), &client->stable_server.port[0], 228 client->os_context); 229 // Nothing read. 230 if (!client->srp_server_synced) { 231 return; 232 } 233 } else { 234 if (update->server != NULL) { 235 return; 236 } 237 } 238 239 // See if one of the advertised servers is the one we last updated. 240 for (server = servers; server; server = server->next) { 241 if (server->rr.type == client->stable_server.rr.type && 242 !memcmp(&server->port, &client->stable_server.port, 2) && 243 ((server->rr.type == dns_rrtype_a && !memcmp(&server->rr.data, &client->stable_server.rr.data, 4)) || 244 (server->rr.type == dns_rrtype_aaaa && !memcmp(&server->rr.data, &client->stable_server.rr.data, 16)))) 245 { 246 update->server = server; 247 return; 248 } 249 } 250 } 251 252 static void 253 sync_to_stable_storage(update_context_t *update) 254 { 255 client_state_t *client = update->client; 256 if (!client->srp_server_synced) { 257 client->srp_server_synced = 258 srp_save_last_server(client->stable_server.rr.type, (uint8_t *)&client->stable_server.rr.data, 259 client->stable_server.rr.type == dns_rrtype_a ? 4 : 16, 260 client->stable_server.port, client->os_context); 261 } 262 } 263 264 // Find an address on a list of addresses. 265 static service_addr_t ** 266 find_address(service_addr_t **addrs, const uint8_t *port, uint16_t rrtype, const uint8_t *rdata, uint16_t rdlen) 267 { 268 service_addr_t *addr, **p_addr = addrs; 269 270 while (*p_addr != NULL) { 271 addr = *p_addr; 272 if (addr->rr.type == rrtype && !memcmp(&addr->rr.data, rdata, rdlen) && !memcmp(addr->port, port, 2)) { 273 break; 274 } 275 p_addr = &addr->next; 276 } 277 return p_addr; 278 } 279 280 // Worker function to add an address and notice whether the network state has changed (so as to trigger a 281 // refresh). 282 static int 283 add_address(service_addr_t **list, service_addr_t **refresh, 284 const uint8_t *port, uint16_t rrtype, const uint8_t *rdata, uint16_t rdlen, bool interface_serial_update) 285 { 286 service_addr_t *addr, **p_addr, **p_refresh; 287 288 VALIDATE_IP_ADDR; 289 290 // See if the address is on the refresh list. 291 p_refresh = find_address(refresh, port, rrtype, rdata, rdlen); 292 293 // See also if it's on the address list (shouldn't be on both). This also finds the end of the list. 294 p_addr = find_address(list, port, rrtype, rdata, rdlen); 295 if (*p_addr != NULL) { 296 return kDNSServiceErr_NoError; 297 } 298 299 if (*p_refresh != NULL) { 300 addr = *p_refresh; 301 302 // This shouldn't happen, but if it does, free the old address. 303 if (*p_addr != NULL) { 304 ERROR("duplicate address during refresh!"); 305 free(addr); 306 return kDNSServiceErr_NoError; 307 } 308 309 *p_refresh = addr->next; 310 addr->next = NULL; 311 *p_addr = addr; 312 313 // In this case, the network state has not changed. 314 return kDNSServiceErr_NoError; 315 } 316 317 addr = calloc(1, sizeof *addr); 318 if (addr == NULL) { 319 return kDNSServiceErr_NoMemory; 320 } 321 addr->rr.type = rrtype; 322 addr->rr.qclass = dns_qclass_in; 323 memcpy(&addr->rr.data, rdata, rdlen); 324 memcpy(&addr->port, port, 2); 325 *p_addr = addr; 326 network_state_changed = true; 327 if (interface_serial_update) { 328 interface_serial++; 329 } 330 331 // Print IPv6 address directly here because the code has to be portable for ADK, and OpenThread environment 332 // has no support for INET6_ADDRSTRLEN. 333 INFO("added " PUB_S_SRP 334 " address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %u (%04x)", 335 *list == servers ? "server" : "interface", 336 rdata[0], rdata[1], rdata[2], rdata[3], rdata[4], rdata[5], rdata[6], rdata[7], 337 rdata[8], rdata[9], rdata[10], rdata[11], rdata[12], rdata[13], rdata[14], rdata[15], 338 port != NULL ? (port[0] << 8 | port[1]) : 0, port != NULL ? (port[0] << 8 | port[1]) : 0); 339 340 return kDNSServiceErr_NoError; 341 } 342 343 // Called when a new address is configured that should be advertised. This can be called during a refresh, 344 // in which case it doesn't mark the network state as changed if the address was already present. 345 int 346 srp_add_interface_address(uint16_t rrtype, const uint8_t *NONNULL rdata, uint16_t rdlen) 347 { 348 return add_address(&interfaces, &interface_refresh_state, no_port, rrtype, rdata, rdlen, true); 349 } 350 351 // Called whenever the SRP server address changes or the SRP server becomes newly reachable. This can be 352 // called during a refresh, in which case it doesn't mark the network state as changed if the address was 353 // already present. 354 int 355 srp_add_server_address(const uint8_t *port, uint16_t rrtype, const uint8_t *NONNULL rdata, uint16_t rdlen) 356 { 357 VALIDATE_IP_ADDR; 358 359 return add_address(&servers, &server_refresh_state, port, rrtype, rdata, rdlen, false); 360 } 361 362 // Called when the node knows its hostname (usually once). The callback is called if we try to do an SRP 363 // update and find out that the hostname is in use; in this case, the callback is expected to generate a new 364 // hostname and re-register it. It is permitted to call srp_set_hostname() from the callback. 365 // If the hostname is changed by the callback, then it is used immediately on return from the callback; 366 // if the hostname is changed in any other situation, nothing is done with the new name until 367 // srp_network_state_stable() is called. 368 int 369 srp_set_hostname(const char *NONNULL name, srp_hostname_conflict_callback_t callback) 370 { 371 if (current_client->hostname != NULL) { 372 free(current_client->hostname); 373 } 374 current_client->hostname = strdup(name); 375 if (current_client->hostname == NULL) { 376 return kDNSServiceErr_NoMemory; 377 } 378 current_client->hostname_conflict_callback = callback; 379 network_state_changed = true; 380 return kDNSServiceErr_NoError; 381 } 382 383 // Called when a network state change is complete (that is, all new addresses have been saved and 384 // any update to the SRP server address has been provided). This is only needed when not using the 385 // refresh mechanism. 386 static bool 387 srp_is_network_active(void) 388 { 389 INFO("nsc = %d servers = %p interfaces = %p, hostname = " PRI_S_SRP, 390 network_state_changed, servers, interfaces, 391 current_client->hostname ? current_client->hostname : "<not set>"); 392 return servers != NULL && (interfaces != NULL || zero_addresses) && current_client->hostname != NULL; 393 } 394 395 int 396 srp_network_state_stable(bool *did_something) 397 { 398 client_state_t *client; 399 int status = kDNSServiceErr_NoError; 400 if (network_state_changed && srp_is_network_active()) { 401 network_state_changed = false; 402 for (client = clients; client; client = client->next) { 403 int ret = do_srp_update(client, false, did_something); 404 // In the normal case, there will only be one client, and therefore one return status. For testing, 405 // we allow more than one client; if we get an error here, we return it, but we still launch all the 406 // updates. 407 if (ret != kDNSServiceErr_NoError && status == kDNSServiceErr_NoError) { 408 status = ret; 409 } 410 } 411 } 412 return kDNSServiceErr_NoError; 413 } 414 415 // Worker function to delete a server or interface address that was previously configured. 416 static int 417 delete_address(service_addr_t **list, const uint8_t *port, uint16_t rrtype, const uint8_t *NONNULL rdata, 418 uint16_t rdlen, bool interface_serial_update) 419 { 420 service_addr_t *addr, **p_addr; 421 422 // Delete API and refresh API are incompatible. 423 if (doing_refresh) { 424 return kDNSServiceErr_BadState; 425 } 426 VALIDATE_IP_ADDR; 427 428 // See if we know this address. 429 p_addr = find_address(list, port, rrtype, rdata, rdlen); 430 if (*p_addr != NULL) { 431 addr = *p_addr; 432 *p_addr = addr->next; 433 free(addr); 434 network_state_changed = true; 435 if (interface_serial_update) { 436 interface_serial++; 437 } 438 return kDNSServiceErr_NoError; 439 } 440 return kDNSServiceErr_NoSuchRecord; 441 } 442 443 // Delete a previously-configured SRP server address. This should not be done during a refresh. 444 int 445 srp_delete_interface_address(uint16_t rrtype, const uint8_t *NONNULL rdata, uint16_t rdlen) 446 { 447 return delete_address(&interfaces, no_port, rrtype, rdata, rdlen, true); 448 } 449 450 // Delete a previously-configured SRP server address. This should not be done during a refresh. 451 int 452 srp_delete_server_address(uint16_t rrtype, const uint8_t *port, const uint8_t *NONNULL rdata, uint16_t rdlen) 453 { 454 return delete_address(&servers, port, rrtype, rdata, rdlen, false); 455 } 456 457 // Call this to start an address refresh. This makes sense to do in cases where the caller 458 // is not tracking changes, but rather is just doing a full refresh whenever the network state 459 // is seen to have changed. When the refresh is done, if any addresses were added or removed, 460 // network_state_changed will be true, and so a call to dnssd_network_state_change_finished() 461 // will trigger an update; if nothing changed, no update will be sent. 462 int 463 srp_start_address_refresh(void) 464 { 465 if (doing_refresh) { 466 return kDNSServiceErr_BadState; 467 } 468 doing_refresh = true; 469 interface_refresh_state = interfaces; 470 server_refresh_state = servers; 471 interfaces = NULL; 472 servers = NULL; 473 network_state_changed = false; 474 return kDNSServiceErr_NoError; 475 } 476 477 // Call this when the address refresh is done. This invokes srp_network_state_stable(). 478 int 479 srp_finish_address_refresh(bool *did_something) 480 { 481 service_addr_t *addr, *next; 482 int i; 483 if (!doing_refresh) { 484 return kDNSServiceErr_BadState; 485 } 486 for (i = 0; i < 2; i++) { 487 if (i == 0) { 488 next = server_refresh_state; 489 server_refresh_state = NULL; 490 } else { 491 if (interface_refresh_state != NULL) { 492 interface_serial++; 493 } 494 next = interface_refresh_state; 495 interface_refresh_state = NULL; 496 } 497 if (next != NULL) { 498 network_state_changed = true; 499 } 500 while (next) { 501 uint8_t *rdata = (uint8_t *)&next->rr.data; 502 // Print IPv6 address directly here because the code has to be portable for ADK, and OpenThread environment 503 // has no support for INET6_ADDRSTRLEN. 504 INFO("deleted " PUB_S_SRP 505 " address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x port %u (%x)", 506 i ? "interface" : "server", 507 rdata[0], rdata[1], rdata[2], rdata[3], rdata[4], rdata[5], rdata[6], rdata[7], 508 rdata[8], rdata[9], rdata[10], rdata[11], rdata[12], rdata[13], rdata[14], rdata[15], 509 (next->port[0] << 8) | next->port[1], (next->port[0] << 8) | next->port[1]); 510 addr = next; 511 next = addr->next; 512 free(addr); 513 } 514 } 515 doing_refresh = false; 516 return srp_network_state_stable(did_something); 517 } 518 519 // Implementation of the API that the application will call to update the TXT record after having registered 520 // a service previously with a different TXT record. In principle this can also update a record added with 521 // DNSServiceAddRecord or DNSServiceRegisterRecord, but we don't support those APIs at present. 522 523 DNSServiceErrorType 524 DNSServiceUpdateRecord(DNSServiceRef sdRef, DNSRecordRef RecordRef, DNSServiceFlags flags, 525 uint16_t rdlen, const void *rdata, uint32_t ttl) 526 { 527 reg_state_t *registration; 528 void *txtRecord = NULL; 529 530 (void)RecordRef; 531 (void)flags; 532 (void)ttl; 533 534 if (sdRef == NULL || RecordRef != NULL || rdata == NULL) { 535 return kDNSServiceErr_Invalid; 536 } 537 538 // Add it to the list (so it will appear valid to DNSServiceRefDeallocate()). 539 for (registration = current_client->registrations; registration != NULL; registration = registration->next) { 540 if (registration == sdRef) { 541 break; 542 } 543 } 544 if (registration == NULL) { 545 return kDNSServiceErr_BadReference; 546 } 547 548 if (rdlen != 0) { 549 txtRecord = malloc(rdlen); 550 if (txtRecord == NULL) { 551 return kDNSServiceErr_NoMemory; 552 } 553 memcpy(txtRecord, rdata, rdlen); 554 } else { 555 registration->txtRecord = NULL; 556 } 557 558 if (registration->txtRecord != NULL) { 559 free(registration->txtRecord); 560 } 561 562 registration->txtRecord = txtRecord; 563 registration->txtLen = rdlen; 564 network_state_changed = true; 565 interface_serial++; 566 return kDNSServiceErr_NoError; 567 } 568 569 // Implementation of the API that applications will call to register services. This is independent of the 570 // hosting platform API. 571 DNSServiceErrorType 572 DNSServiceRegister(DNSServiceRef *sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, 573 const char *NULLABLE name, const char *NULLABLE regtype, const char *NULLABLE domain, 574 const char *NULLABLE host, uint16_t port, 575 uint16_t txtLen, const void *txtRecord, 576 DNSServiceRegisterReply callBack, void *context) 577 { 578 reg_state_t **rp, *reg = calloc(1, sizeof *reg); 579 if (reg == NULL) { 580 return kDNSServiceErr_NoMemory; 581 } 582 583 // Add it to the list (so it will appear valid to DNSServiceRefDeallocate()). 584 rp = ¤t_client->registrations; 585 while (*rp) { 586 rp = &((*rp)->next); 587 } 588 *rp = reg; 589 590 // If we don't already have a hostname, use the one from the registration. 591 if (current_client->hostname == NULL) { 592 srp_set_hostname(host, NULL); 593 } 594 595 reg->serial = current_client->registration_serial++; 596 reg->flags = flags; 597 reg->interfaceIndex = interfaceIndex; 598 reg->called_back = true; 599 #define stashName(thing) \ 600 if (thing != NULL) { \ 601 reg->thing = strdup(thing); \ 602 if (reg->thing == NULL) { \ 603 DNSServiceRefDeallocate(reg); \ 604 return kDNSServiceErr_NoMemory; \ 605 } \ 606 } else { \ 607 reg->thing = NULL; \ 608 } 609 stashName(name); 610 stashName(regtype); 611 stashName(domain); 612 stashName(host); 613 reg->port = port; 614 reg->txtLen = txtLen; 615 if (txtLen != 0) { 616 reg->txtRecord = malloc(txtLen); 617 if (reg->txtRecord == NULL) { 618 DNSServiceRefDeallocate(reg); 619 return kDNSServiceErr_NoMemory; 620 } 621 memcpy(reg->txtRecord, txtRecord, txtLen); 622 } else { 623 reg->txtRecord = NULL; 624 } 625 reg->callback = callBack; 626 reg->context = context; 627 *sdRef = reg; 628 network_state_changed = true; 629 return kDNSServiceErr_NoError; 630 } 631 632 DNSServiceErrorType 633 srp_update_service_type(DNSServiceRef NONNULL reg, const char *NONNULL regtype, DNSServiceRegisterReply callback, void *context) 634 { 635 if (reg != NULL) { 636 client_state_t *client = NULL; 637 638 for (client_state_t *cp = clients; client == NULL && cp != NULL; cp = cp->next) { 639 // Remove it from the list. 640 for (reg_state_t *rp = cp->registrations; client == NULL && rp != NULL; rp = rp->next) { 641 if (rp == reg) { 642 client = cp; 643 } 644 } 645 } 646 if (client == NULL) { 647 return kDNSServiceErr_Unknown; 648 } 649 650 stashName(regtype); 651 reg->serial = client->registration_serial++; 652 reg->callback = callback; 653 reg->context = context; 654 network_state_changed = true; 655 } else { 656 return kDNSServiceErr_Invalid; 657 } 658 return kDNSServiceErr_NoError; 659 } 660 661 void 662 DNSServiceRefDeallocate(DNSServiceRef sdRef) 663 { 664 reg_state_t **rp, *reg = NULL; 665 bool found = false; 666 client_state_t *client; 667 668 if (sdRef == NULL) { 669 return; 670 } 671 672 for (client = clients; client; client = client->next) { 673 // Remove it from the list. 674 rp = &client->registrations; 675 reg = *rp; 676 while (*rp) { 677 if (reg == sdRef) { 678 *rp = reg->next; 679 found = true; 680 break; 681 } 682 rp = &((*rp)->next); 683 reg = *rp; 684 } 685 686 if (found) { 687 break; 688 } 689 } 690 691 // This avoids a bogus free. 692 if (!found || reg == NULL) { 693 return; 694 } 695 if (reg->name != NULL) { 696 free(reg->name); 697 } 698 if (reg->regtype != NULL) { 699 free(reg->regtype); 700 } 701 if (reg->domain != NULL) { 702 free(reg->domain); 703 } 704 if (reg->host != NULL) { 705 free(reg->host); 706 } 707 if (reg->txtRecord != NULL) { 708 free(reg->txtRecord); 709 } 710 free(reg); 711 } 712 713 static void 714 update_finalize(update_context_t *update) 715 { 716 client_state_t *client = update->client; 717 INFO("%p %p %p", update, update->udp_context, update->message); 718 if (update->udp_context != NULL) { 719 srp_deactivate_udp_context(client->os_context, update->udp_context); 720 } 721 if (update->message != NULL) { 722 free(update->message); 723 } 724 free(update); 725 } 726 727 static void 728 do_callbacks(client_state_t *client, reg_state_t *registration, uint32_t serial, int err, bool succeeded) 729 { 730 reg_state_t *rp; 731 bool work; 732 733 // The callback can modify the list, so we use a marker to remember where we are in the list rather 734 // than remembering a pointer which could be invalidated. If a callback adds a registration, that 735 // registration doesn't get called because called_back is set to true when a registration is added. 736 for (rp = client->registrations; rp; rp = rp->next) { 737 if (rp->serial <= serial) { 738 rp->called_back = false; 739 } 740 } 741 do { 742 work = false; 743 for (rp = client->registrations; rp; rp = rp->next) { 744 if (registration != NULL && registration != rp) { 745 continue; 746 } 747 if (rp->serial > serial || rp->callback == NULL || rp->called_back) { 748 continue; 749 } 750 work = true; 751 rp->called_back = true; 752 if (succeeded) { 753 rp->succeeded = true; 754 } 755 if (rp->callback != NULL) { 756 rp->callback(rp, kDNSServiceFlagsAdd, err, rp->name, rp->regtype, rp->domain, rp->context); 757 break; 758 } 759 } 760 } while (work); 761 } 762 763 static void 764 udp_retransmit(void *v_update_context) 765 { 766 update_context_t *context = v_update_context; 767 client_state_t *client; 768 service_addr_t *next_server = NULL; 769 int err; 770 771 client = context->client; 772 773 if (!srp_is_network_active()) { 774 INFO("network is down, discontinuing renewals."); 775 if (client->active_update != NULL) { 776 update_finalize(client->active_update); 777 client->active_update = NULL; 778 } 779 return; 780 } 781 // It shouldn't be possible for this to happen. 782 if (client->active_update == NULL) { 783 INFO("no active update for " PRI_S_SRP " (%p).", 784 client->hostname ? client->hostname : "<null>", client); 785 return; 786 } 787 INFO("next_attempt %" PRIu32 " next_retransmission %" PRIu32 " for " PRI_S_SRP " (%p)", 788 context->next_attempt_time, context->next_retransmission_time, 789 client->hostname ? client->hostname : "<null>", client); 790 791 // If the interface serial number has changed, we need to generate a new update message. 792 if (client->active_update->interface_serial != interface_serial) { 793 client->active_update->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 794 client->active_update->next_attempt_time = INITIAL_NEXT_ATTEMPT_TIME; 795 free(context->message); 796 context->message = NULL; 797 } 798 799 // If next retransmission time is zero, this means that we gave up our last attempt to register, and have 800 // now waited long enough to try again. We will then use an exponential backoff for 90 seconds before giving 801 // up again; if we give up again, we will wait longer to retry, up to an hour. 802 else if (context->next_retransmission_time == 0) { 803 // If there are no servers, we don't need to schedule a re-attempt: when a server is seen, we will do 804 // an update immediately. 805 if (servers == NULL) { 806 return; 807 } 808 next_server = servers; 809 810 // If this attempt fails, don't try again for a while longer, but limit the retry interval to an hour. 811 context->next_attempt_time *= 2; 812 if (context->next_attempt_time > client->srp_max_attempt_interval) { 813 context->next_attempt_time = client->srp_max_attempt_interval; 814 } 815 context->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 816 } 817 // If this would be our fourth retry on a particular server, try the next server. 818 else if (context->next_retransmission_time > client->srp_max_retry_interval) { 819 // If we are removing, there is no point in trying the next server--just give up and report a timeout. 820 if (context->removing) { 821 do_callbacks(client, NULL, context->serial, kDNSServiceErr_Timeout, false); 822 // Once the goodbye retransmission has timed out, we're done. 823 return; 824 } 825 for (next_server = servers; next_server; next_server = next_server->next) { 826 if (next_server == context->server) { 827 // We're going to use the next server after the one we just tried. If we run out of servers, 828 // we'll give up for a while. 829 next_server = next_server->next; 830 break; 831 } 832 } 833 834 // If we run off the end of the list, give up for a bit. 835 if (next_server == NULL) { 836 context->next_retransmission_time = 0; 837 } else { 838 context->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 839 } 840 } 841 // Otherwise, we are still trying to win with a particular server, so back off exponentially. 842 else { 843 context->next_retransmission_time *= 2; 844 } 845 846 // If we are giving up on the current server, get rid of any udp state. 847 if (context->next_retransmission_time == 0 || next_server != NULL) { 848 if (next_server != NULL) { 849 context->server = next_server; 850 } 851 srp_disconnect_udp(context->udp_context); 852 context->connected = false; 853 if (context->message != NULL) { 854 free(context->message); 855 } 856 context->message = NULL; 857 context->message_length = 0; 858 context->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 859 context->next_attempt_time = INITIAL_NEXT_ATTEMPT_TIME; 860 } 861 862 // If we are not giving up, send the next packet. 863 if (context->server != NULL && context->next_retransmission_time != 0) { 864 if (!context->connected) { 865 // Create a UDP context for this transaction. 866 err = srp_connect_udp(context->udp_context, context->server->port, context->server->rr.type, 867 (uint8_t *)&context->server->rr.data, 868 context->server->rr.type == dns_rrtype_a ? 4 : 16); 869 // In principle if it fails here, it might succeed later, so we just don't send a packet and let 870 // the timeout take care of it. 871 if (err != kDNSServiceErr_NoError) { 872 ERROR("udp_retransmit: error %d connecting udp context.", err); 873 } else { 874 if (context->server->rr.type == dns_rrtype_a) { 875 #ifdef THREAD_DEVKIT_ADK 876 INFO("updating server at address %d.%d.%d.%d", (context->server->rr.data.a.s_addr >> 24) & 255, 877 (context->server->rr.data.a.s_addr >> 16) & 255, 878 (context->server->rr.data.a.s_addr >> 8) & 255, (context->server->rr.data.a.s_addr) & 255); 879 #else 880 IPv4_ADDR_GEN_SRP(&context->server->rr.data.a, addr_buf); 881 INFO("updating server at address " PRI_IPv4_ADDR_SRP, 882 IPv4_ADDR_PARAM_SRP(&context->server->rr.data.a, addr_buf)); 883 #endif 884 } else if (context->server->rr.type == dns_rrtype_aaaa) { 885 #ifdef THREAD_DEVKIT_ADK 886 INFO("updating server at address " 887 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", 888 context->server->rr.data.aaaa.s6_addr[0], context->server->rr.data.aaaa.s6_addr[1], 889 context->server->rr.data.aaaa.s6_addr[2], context->server->rr.data.aaaa.s6_addr[3], 890 context->server->rr.data.aaaa.s6_addr[4], context->server->rr.data.aaaa.s6_addr[5], 891 context->server->rr.data.aaaa.s6_addr[6], context->server->rr.data.aaaa.s6_addr[7], 892 context->server->rr.data.aaaa.s6_addr[8], context->server->rr.data.aaaa.s6_addr[9], 893 context->server->rr.data.aaaa.s6_addr[10], context->server->rr.data.aaaa.s6_addr[11], 894 context->server->rr.data.aaaa.s6_addr[12], context->server->rr.data.aaaa.s6_addr[13], 895 context->server->rr.data.aaaa.s6_addr[14], context->server->rr.data.aaaa.s6_addr[15]); 896 #else 897 SEGMENTED_IPv6_ADDR_GEN_SRP(&context->server->rr.data.aaaa, addr_buf); 898 INFO("updating server at address " PRI_SEGMENTED_IPv6_ADDR_SRP, 899 SEGMENTED_IPv6_ADDR_PARAM_SRP(&context->server->rr.data.aaaa, addr_buf)); 900 #endif 901 } 902 context->connected = true; 903 } 904 } 905 906 if (context->message == NULL) { 907 context->message = srp_client_generate_update(client, client->lease_time, client->key_lease_time, 908 &context->message_length, NULL, context->serial, 909 context->removing); 910 if (context->message == NULL) { 911 ERROR("No memory for message."); 912 return; 913 } 914 } 915 916 if (context->connected) { 917 // Send the datagram to the server 918 err = srp_send_datagram(client->os_context, context->udp_context, context->message, context->message_length); 919 if (err != kDNSServiceErr_NoError) { 920 ERROR("udp_retransmit: error %d sending a datagram.", err); 921 } 922 } 923 } 924 925 // If we've given up for now, either schedule a next attempt or notify the caller; otherwise, schedule the next retransmission. 926 if (context->next_retransmission_time == 0) { 927 bool timeout_requested = false; 928 reg_state_t *registration; 929 for (registration = client->registrations; registration; registration = registration->next) { 930 if (registration->callback != NULL && registration->serial <= context->serial && 931 (registration->flags & kDNSServiceFlagsTimeout)) 932 { 933 timeout_requested = true; 934 } 935 } 936 // If any of the callers requested a timeout, we treat it as if they all did, and call all the callbacks with the "timed out" 937 // error. 938 if (timeout_requested) { 939 do_callbacks(client, NULL, context->serial, kDNSServiceErr_Timeout, false); 940 err = kDNSServiceErr_NoError; 941 } else { 942 err = srp_set_wakeup(client->os_context, context->udp_context, context->next_attempt_time, udp_retransmit); 943 } 944 } else { 945 err = srp_set_wakeup(client->os_context, context->udp_context, 946 context->next_retransmission_time - 512 + srp_random16() % 1024, udp_retransmit); 947 } 948 if (err != kDNSServiceErr_NoError) { 949 INFO("error %d setting wakeup", err); 950 // what to do? 951 } 952 } 953 954 static void 955 renew_callback(void *v_update_context) 956 { 957 update_context_t *context = v_update_context; 958 client_state_t *client = context->client; 959 INFO("renew callback"); 960 do_srp_update(client, true, NULL); 961 } 962 963 // This function will, if hostname_rename_number is nonzero, create a hostname using the chosen hostname plus 964 // space plus the number as ascii text. The caller is responsible for freeing the return value if it's not NULL. 965 static char * 966 conflict_print(client_state_t *client, dns_towire_state_t *towire, char **return_hostname, char *chosen_hostname) 967 { 968 char *conflict_hostname; 969 size_t hostname_len; 970 971 if (client->hostname_rename_number == 0) { 972 *return_hostname = chosen_hostname; 973 return NULL; 974 } 975 976 hostname_len = strlen(chosen_hostname); 977 // 7 is max length of decimal short (5) plus space plus NUL 978 if (hostname_len + 7 > DNS_MAX_LABEL_SIZE) { 979 hostname_len = DNS_MAX_LABEL_SIZE - 7; 980 } 981 conflict_hostname = malloc(hostname_len + 7); 982 if (conflict_hostname == NULL) { 983 if (towire != NULL) { 984 towire->line = __LINE__; 985 towire->outer_line = -1; 986 towire->error = true; 987 } 988 *return_hostname = chosen_hostname; 989 return NULL; 990 } 991 992 memcpy(conflict_hostname, chosen_hostname, hostname_len); 993 snprintf(conflict_hostname + hostname_len, 7, " %d", client->hostname_rename_number); 994 *return_hostname = conflict_hostname; 995 return conflict_hostname; 996 } 997 998 static void 999 udp_response(void *v_update_context, void *v_message, size_t message_length) 1000 { 1001 update_context_t *context = v_update_context; 1002 client_state_t *client = context->client; 1003 dns_wire_t *message = v_message; 1004 int err; 1005 int rcode = dns_rcode_get(message); 1006 (void)message_length; 1007 uint32_t new_lease_time = 0; 1008 bool lease_time_sent = false; 1009 reg_state_t *registration; 1010 const uint8_t *p = message->data; 1011 const uint8_t *end = (const uint8_t *)v_message + message_length; 1012 bool resolve_name_conflict = false; 1013 char *conflict_hostname = NULL, *chosen_hostname; 1014 1015 INFO("Got a response for %p, rcode = %d", client, dns_rcode_get(message)); 1016 1017 // Cancel the existing retransmit wakeup, since we definitely don't want to retransmit to the current 1018 // server. 1019 err = srp_cancel_wakeup(client->os_context, context->udp_context); 1020 if (err != kDNSServiceErr_NoError) { 1021 INFO("%d", err); 1022 } 1023 1024 // We want a different UDP source port for each transaction, so cancel the current UDP state. 1025 srp_disconnect_udp(context->udp_context); 1026 if (context->message != NULL) { 1027 free(context->message); 1028 } 1029 context->message = NULL; 1030 context->message_length = 0; 1031 context->connected = false; 1032 context->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 1033 context->next_attempt_time = INITIAL_NEXT_ATTEMPT_TIME; 1034 1035 // When we are doing a remove, we don't actually care what the result is--if we get back an answer, we call 1036 // the callback. 1037 if (context->removing) { 1038 do_callbacks(client, NULL, context->serial, kDNSServiceErr_NoSuchRecord, false); 1039 goto out; 1040 } 1041 1042 // Deal with the response. 1043 switch (rcode) { 1044 case dns_rcode_noerror: 1045 // Remember the server we connected with. active_update and active_update->server should always be 1046 // non-NULL here. 1047 if (client->active_update != NULL) { 1048 if (client->active_update->server != NULL) { 1049 // If the new server is not the one that's mentioned in stable_server, then update the one 1050 // in stable_server. 1051 if (client->active_update->server->rr.type != client->stable_server.rr.type || 1052 (client->stable_server.rr.type == dns_rrtype_a 1053 ? memcmp(&client->stable_server.rr.data, &client->active_update->server->rr.data, 4) 1054 : (client->stable_server.rr.type == dns_rrtype_aaaa 1055 ? memcmp(&client->stable_server.rr.data, &client->active_update->server->rr.data, 16) 1056 : true)) || 1057 memcmp(client->stable_server.port, client->active_update->server->port, 2)) 1058 { 1059 memcpy(&client->stable_server, client->active_update->server, sizeof(client->stable_server)); 1060 client->srp_server_synced = false; 1061 } 1062 sync_to_stable_storage(client->active_update); 1063 } 1064 client->active_update->interface_serial = interface_serial; 1065 } 1066 1067 for (reg_state_t *rp = client->registrations; rp != NULL; rp = rp->next) { 1068 if (rp->removing) { 1069 INFO("removal for " PRI_S_SRP "." PRI_S_SRP " completed.", rp->name, rp->regtype); 1070 do_callbacks(client, rp, context->serial, kDNSServiceErr_NoSuchRecord, false); 1071 rp->skip = true; // The caller should do DNSServiceRefDeallocate, but if they don't, we don't want 1072 // to either continually send removes, nor to send the update again. 1073 } 1074 } 1075 1076 // Get the renewal time 1077 // At present, there's no code to actually parse a real DNS packet in the client, so 1078 // we rely on the server returning just an EDNS0 option; if this assumption fails, we 1079 // are out of luck. 1080 if (message->qdcount == 0 && message->ancount == 0 && message->nscount == 0 && ntohs(message->arcount) == 1 && 1081 // We expect the edns0 option to be: 1082 // root label - 1 byte 1083 // type = 2 bytes 1084 // class = 2 bytes 1085 // ttl = 4 bytes 1086 // rdlength = 2 bytes 1087 // total of 11 bytes 1088 // data 1089 end - p > 11 && // Enough room for an EDNS0 option 1090 *p == 0 && // root label 1091 p[1] == (dns_rrtype_opt >> 8) && p[2] == (dns_rrtype_opt & 255)) // opt rrtype 1092 { 1093 // skip class and ttl, we don't care 1094 const uint8_t *opt_start = &p[11]; // Start of opt data 1095 uint16_t opt_len = (((uint16_t)p[9]) << 8) + p[10]; // length of opt data 1096 const uint8_t *opt_cur = opt_start; 1097 uint16_t opt_remaining = opt_len; 1098 // Scan for options until there's no room. 1099 while (opt_cur + 4 <= end) { 1100 int option_code = (((uint16_t)opt_cur[0]) << 8) + opt_cur[1]; 1101 int option_len = (((uint16_t)opt_cur[2]) << 8) + opt_cur[3]; 1102 const uint8_t *option_data = opt_cur + 4; 1103 if (option_len + option_data <= end) { 1104 if (option_code == dns_opt_update_lease) { 1105 if (option_len == 8) { 1106 new_lease_time = (((uint32_t)option_data[0] << 24) | ((uint32_t)option_data[1] << 16) | 1107 ((uint32_t)option_data[2] << 8) | ((uint32_t)option_data[3])); 1108 INFO("Lease time set to %" PRIu32, new_lease_time); 1109 lease_time_sent = true; 1110 } 1111 } 1112 } 1113 opt_cur = option_data + option_len; 1114 opt_remaining = opt_remaining - (option_len + 4); 1115 } 1116 } 1117 1118 if (!lease_time_sent) { 1119 new_lease_time = context->lease_time; 1120 INFO("Lease time defaults to %" PRIu32, new_lease_time); 1121 DEBUG("len %zd qd %d an %d ns %d ar %d data %02x %02x %02x %02x %02x %02x %02x %02x %02x" 1122 " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", 1123 end - p, ntohs(message->qdcount), ntohs(message->ancount), 1124 ntohs(message->nscount), ntohs(message->arcount), 1125 p[0], p[1], p[2], p[3], p[3], p[5], p[6], p[7], p[8], p[9], p[10], p[11], 1126 p[12], p[13], p[14], p[15], p[16], p[17], p[18], p[19], p[20], p[21], p[22]); 1127 } 1128 1129 // Set up to renew. Time is in milliseconds, and we want to renew at 80% of the lease time. 1130 srp_set_wakeup(client->os_context, context->udp_context, (new_lease_time * 1000) * 8 / 10, renew_callback); 1131 1132 do_callbacks(client, NULL, context->serial, kDNSServiceErr_NoError, true); 1133 break; 1134 case dns_rcode_yxdomain: 1135 // Get the actual hostname that we sent. 1136 if (client->hostname_conflict_callback != NULL && client->hostname != NULL) { 1137 conflict_hostname = conflict_print(client, NULL, &chosen_hostname, client->hostname); 1138 client->hostname_conflict_callback(chosen_hostname); 1139 if (conflict_hostname != NULL) { 1140 free(conflict_hostname); 1141 } 1142 } 1143 1144 bool resolve_with_callback = false; 1145 for (registration = client->registrations; registration; registration = registration->next) { 1146 if (registration->callback != NULL && registration->serial <= context->serial && 1147 (registration->flags & kDNSServiceFlagsNoAutoRename)) 1148 { 1149 resolve_with_callback = true; 1150 } 1151 } 1152 if (resolve_with_callback) { 1153 do_callbacks(client, NULL, context->serial, kDNSServiceErr_NameConflict, false); 1154 resolve_name_conflict = false; 1155 } else { 1156 resolve_name_conflict = true; 1157 } 1158 1159 if (resolve_name_conflict) { 1160 // If we get a name conflict, try using a low number to rename, but only twice; it's time consuming to do 1161 // this, so if we get two conflicts, we switch to using a random number. 1162 if (client->hostname_rename_number < 2) { 1163 client->hostname_rename_number++; 1164 } else { 1165 client->hostname_rename_number = srp_random16(); 1166 } 1167 // When we get a name conflict response, we need to re-do the update immediately 1168 // (with a 0-500ms delay of course). 1169 do_srp_update(client, true, NULL); 1170 return; 1171 } 1172 break; 1173 1174 default: 1175 // If we get here, it means that the server failed to process the transmission, and there is no 1176 // action we can take to change the situation other than trying another server. We set the 1177 // retransmission time for the current server long enough to force a switch to the next server, 1178 // if any. 1179 context->next_retransmission_time = client->srp_max_retry_interval + 1; 1180 err = srp_set_wakeup(client->os_context, context->udp_context, 1181 context->next_retransmission_time - 512 + srp_random16() % 1024, udp_retransmit); 1182 return; 1183 } 1184 out: 1185 if (client->active_update != NULL) { 1186 client->active_update->serial = client->registration_serial; 1187 } 1188 } 1189 1190 // Generate a new SRP update message 1191 dns_wire_t * 1192 srp_client_generate_update(client_state_t *client, uint32_t update_lease_time, uint32_t update_key_lease_time, 1193 size_t *NONNULL p_length, dns_wire_t *in_wire, uint32_t serial, bool removing) 1194 { 1195 dns_wire_t *message; 1196 const char *zone_name = "default.service.arpa"; 1197 const char *service_type = "_ipps._tcp"; 1198 const char *txt_record = "0"; 1199 uint16_t key_tag; 1200 dns_towire_state_t towire; 1201 dns_name_pointer_t p_host_name; 1202 dns_name_pointer_t p_zone_name; 1203 dns_name_pointer_t p_service_name; 1204 dns_name_pointer_t p_service_instance_name; 1205 int line; 1206 service_addr_t *addr; 1207 reg_state_t *reg; 1208 char *conflict_hostname = NULL, *chosen_hostname; 1209 1210 #define INCREMENT(x) (x) = htons(ntohs(x) + 1) 1211 memset(&towire, 0, sizeof towire); 1212 1213 // Get the key if we don't already have it. 1214 if (client->key == NULL) { 1215 client->key = srp_get_key("com.apple.srp-client.host-key", client->os_context); 1216 if (client->key == NULL) { 1217 INFO("No key gotten."); 1218 return NULL; 1219 } 1220 } 1221 1222 #define CH if (towire.error) { line = __LINE__; goto fail; } 1223 1224 if (client->hostname == NULL) { 1225 ERROR("called with NULL hostname."); 1226 return NULL; 1227 } 1228 1229 // If we were given a message buffer, use it, otherwise allocate one. 1230 if (in_wire != NULL) { 1231 message = in_wire; 1232 towire.p = &message->data[0]; 1233 towire.lim = towire.p + *p_length; 1234 towire.message = in_wire; 1235 } else { 1236 // Allocate a message buffer. 1237 message = calloc(1, sizeof *message); 1238 if (message == NULL) { 1239 return NULL; 1240 } 1241 towire.p = &message->data[0]; // We start storing RR data here. 1242 towire.lim = &message->data[DNS_DATA_SIZE]; // This is the limit to how much we can store. 1243 towire.message = message; 1244 } 1245 1246 // Generate a random UUID. 1247 message->id = srp_random16(); 1248 message->bitfield = 0; 1249 dns_qr_set(message, dns_qr_query); 1250 dns_opcode_set(message, dns_opcode_update); 1251 1252 message->qdcount = 0; 1253 // Copy in Zone name (and save pointer) 1254 // ZTYPE = SOA 1255 // ZCLASS = IN 1256 dns_full_name_to_wire(&p_zone_name, &towire, zone_name); CH; 1257 dns_u16_to_wire(&towire, dns_rrtype_soa); CH; 1258 dns_u16_to_wire(&towire, dns_qclass_in); CH; 1259 INCREMENT(message->qdcount); 1260 1261 message->ancount = 0; 1262 // PRCOUNT = 0 1263 1264 message->nscount = 0; 1265 // UPCOUNT = ... 1266 1267 // Host Description: 1268 // * Delete all RRsets from <hostname>; remember the pointer to hostname 1269 // NAME = hostname label followed by pointer to SOA name. 1270 // TYPE = ANY 1271 // CLASS = ANY 1272 // TTL = 0 1273 // RDLENGTH = 0 1274 1275 conflict_hostname = conflict_print(client, &towire, &chosen_hostname, client->hostname); CH; 1276 dns_name_to_wire(&p_host_name, &towire, chosen_hostname); CH; 1277 dns_pointer_to_wire(&p_host_name, &towire, &p_zone_name); CH; 1278 dns_u16_to_wire(&towire, dns_rrtype_any); CH; 1279 dns_u16_to_wire(&towire, dns_qclass_any); CH; 1280 dns_ttl_to_wire(&towire, 0); CH; 1281 dns_u16_to_wire(&towire, 0); CH; 1282 INCREMENT(message->nscount); 1283 1284 // * Add addresses: A and/or AAAA RRsets, each of which contains one 1285 // or more A or AAAA RRs. 1286 // NAME = pointer to hostname from Delete (above) 1287 // TYPE = A or AAAA 1288 // CLASS = IN 1289 // TTL = 3600 ? 1290 // RDLENGTH = number of RRs * RR length (4 or 16) 1291 // RDATA = <the data> 1292 if (!removing) { 1293 for (addr = interfaces; addr; addr = addr->next) { 1294 dns_pointer_to_wire(NULL, &towire, &p_host_name); CH; 1295 dns_u16_to_wire(&towire, addr->rr.type); CH; 1296 dns_u16_to_wire(&towire, dns_qclass_in); CH; 1297 dns_ttl_to_wire(&towire, 3600); CH; 1298 dns_rdlength_begin(&towire); CH; 1299 dns_rdata_raw_data_to_wire(&towire, &addr->rr.data, 1300 addr->rr.type == dns_rrtype_a ? 4 : 16); CH; 1301 dns_rdlength_end(&towire); CH; 1302 INCREMENT(message->nscount); 1303 } 1304 } 1305 1306 // * Exactly one KEY RR: 1307 // NAME = pointer to hostname from Delete (above) 1308 // TYPE = KEY 1309 // CLASS = IN 1310 // TTL = 3600 1311 // RDLENGTH = length of key + 4 (32 bits) 1312 // RDATA = <flags(16) = 0000 0010 0000 0001, protocol(8) = 3, algorithm(8) = 8?, public key(variable)> 1313 dns_pointer_to_wire(NULL, &towire, &p_host_name); CH; 1314 dns_u16_to_wire(&towire, dns_rrtype_key); CH; 1315 dns_u16_to_wire(&towire, dns_qclass_in); CH; 1316 dns_ttl_to_wire(&towire, 3600); CH; 1317 dns_rdlength_begin(&towire); CH; 1318 key_tag = dns_rdata_key_to_wire(&towire, 0, 2, 1, client->key); CH; 1319 dns_rdlength_end(&towire); CH; 1320 INCREMENT(message->nscount); 1321 1322 // If we are removing the host, we don't need to send instances. 1323 if (!removing) { 1324 1325 // Emit any registrations. 1326 for (reg = client->registrations; reg; reg = reg->next) { 1327 // Only remove the registrations that are actually registered. Normally this will be all of them, but it's 1328 // possible for a registration to be added but not to have been updated yet, and then for us to get a remove 1329 // call, in which case we don't need to remove it. 1330 if (((removing || reg->removing) && reg->serial > serial) || reg->skip) { 1331 continue; 1332 } 1333 1334 // Service: 1335 // * Update PTR RR 1336 // NAME = service name (_a._b.service.arpa) 1337 // TYPE = PTR 1338 // CLASS = IN 1339 // TTL = 3600 1340 // RDLENGTH = 2 1341 // RDATA = service instance name 1342 1343 // Service registrations can have subtypes, in which case we need to send multiple PTR records, one for 1344 // the main type and one for each subtype. Subtypes are represented in the regtype by following the 1345 // primary service type with subtypes, separated by commas. So we have to parse through that to get 1346 // the actual domain names to register. 1347 const char *commap = reg->regtype == NULL ? service_type : reg->regtype; 1348 dns_name_pointer_t p_sub_service_name; 1349 bool primary = true; 1350 do { 1351 char regtype[DNS_MAX_LABEL_SIZE_ESCAPED + 6]; // plus NUL, ._sub 1352 int i; 1353 // Copy the next service type into regtype, ending when we hit the end of reg->regtype 1354 // or when we hit a comma. 1355 for (i = 0; *commap != '\0' && *commap != ',' && i < DNS_MAX_LABEL_SIZE_ESCAPED; i++) { 1356 regtype[i] = *commap; 1357 commap++; 1358 } 1359 1360 // If we hit a comma, skip over the comma for the beginning of the next subtype. 1361 if (*commap == ',') { 1362 commap++; 1363 } 1364 1365 // If we aren't at a NULL or a comma, it means that the label was too long, so the output 1366 // is invalid. 1367 else if (*commap != '\0') { 1368 towire.error = ENOBUFS; CH; 1369 } 1370 1371 // First time through, it's the base type, so emit the service name and a pointer to the 1372 // zone name. Other times through, it's a subtype, so the pointer is now to the base type, 1373 // and since the API makes ._sub implicit, we have to add that. 1374 if (primary) { 1375 regtype[i] = 0; 1376 dns_name_to_wire(&p_service_name, &towire, regtype); CH; 1377 dns_pointer_to_wire(&p_service_name, &towire, &p_zone_name); CH; 1378 } else { 1379 // Copy in the string and the NUL. We know there's space (see above). 1380 memcpy(®type[i], "._sub", 6); 1381 dns_name_to_wire(&p_sub_service_name, &towire, regtype); CH; 1382 dns_pointer_to_wire(&p_sub_service_name, &towire, &p_service_name); CH; 1383 } 1384 dns_u16_to_wire(&towire, dns_rrtype_ptr); CH; 1385 if (reg->removing) { 1386 dns_u16_to_wire(&towire, dns_qclass_none); CH; 1387 dns_ttl_to_wire(&towire, 0); CH; 1388 } else { 1389 dns_u16_to_wire(&towire, dns_qclass_in); CH; 1390 dns_ttl_to_wire(&towire, 3600); CH; 1391 } 1392 dns_rdlength_begin(&towire); CH; 1393 if (reg->name != NULL) { 1394 char *service_instance_name, *to_free = conflict_print(client, &towire, &service_instance_name, reg->name); 1395 dns_name_to_wire(&p_service_instance_name, &towire, service_instance_name); CH; 1396 if (to_free != NULL) { 1397 free(to_free); 1398 } 1399 } else { 1400 dns_name_to_wire(&p_service_instance_name, &towire, chosen_hostname); CH; 1401 } 1402 dns_pointer_to_wire(&p_service_instance_name, &towire, &p_service_name); CH; 1403 dns_rdlength_end(&towire); CH; 1404 INCREMENT(message->nscount); 1405 primary = false; 1406 // We don't need to remove subtypes: removing the instance removes all its subtypes. 1407 if (reg->removing) { 1408 break; 1409 } 1410 } while (*commap != '\0'); 1411 1412 // Service Instance: 1413 // * Delete all RRsets from service instance name 1414 // NAME = service instance name (save pointer to service name, which is the second label) 1415 // TYPE = ANY 1416 // CLASS = ANY 1417 // TTL = 0 1418 // RDLENGTH = 0 1419 dns_pointer_to_wire(NULL, &towire, &p_service_instance_name); CH; 1420 dns_u16_to_wire(&towire, dns_rrtype_any); CH; 1421 dns_u16_to_wire(&towire, dns_qclass_any); CH; 1422 dns_ttl_to_wire(&towire, 0); CH; 1423 dns_u16_to_wire(&towire, 0); CH; 1424 INCREMENT(message->nscount); 1425 1426 if (!reg->removing) { 1427 // * Add one SRV RRset pointing to Host Description 1428 // NAME = pointer to service instance name from above 1429 // TYPE = SRV 1430 // CLASS = IN 1431 // TTL = 3600 1432 // RDLENGTH = 8 1433 // RDATA = <priority(16) = 0, weight(16) = 0, port(16) = service port, target = pointer to hostname> 1434 dns_pointer_to_wire(NULL, &towire, &p_service_instance_name); CH; 1435 dns_u16_to_wire(&towire, dns_rrtype_srv); CH; 1436 dns_u16_to_wire(&towire, dns_qclass_in); CH; 1437 dns_ttl_to_wire(&towire, 3600); CH; 1438 dns_rdlength_begin(&towire); CH; 1439 dns_u16_to_wire(&towire, 0); CH; // priority 1440 dns_u16_to_wire(&towire, 0); CH; // weight 1441 dns_u16_to_wire(&towire, reg->port); CH; // port 1442 dns_pointer_to_wire(NULL, &towire, &p_host_name); CH; 1443 dns_rdlength_end(&towire); CH; 1444 INCREMENT(message->nscount); 1445 1446 // * Add one or more TXT records 1447 // NAME = pointer to service instance name from above 1448 // TYPE = TXT 1449 // CLASS = IN 1450 // TTL = 3600 1451 // RDLENGTH = <length of text> 1452 // RDATA = <text> 1453 dns_pointer_to_wire(NULL, &towire, &p_service_instance_name); CH; 1454 dns_u16_to_wire(&towire, dns_rrtype_txt); CH; 1455 dns_u16_to_wire(&towire, dns_qclass_in); CH; 1456 dns_ttl_to_wire(&towire, 3600); CH; 1457 dns_rdlength_begin(&towire); CH; 1458 if (reg->txtRecord != NULL) { 1459 dns_rdata_raw_data_to_wire(&towire, reg->txtRecord, reg->txtLen); 1460 } else { 1461 dns_rdata_txt_to_wire(&towire, txt_record); CH; 1462 } 1463 dns_rdlength_end(&towire); CH; 1464 INCREMENT(message->nscount); 1465 } 1466 } 1467 } 1468 1469 // What about services with more than one name? Are these multiple service descriptions? 1470 1471 // ARCOUNT = 2 1472 // EDNS(0) options 1473 // ... 1474 // SIG(0) 1475 1476 message->arcount = 0; 1477 dns_edns0_header_to_wire(&towire, DNS_MAX_UDP_PAYLOAD, 0, 0, 1); CH; // XRCODE = 0; VERSION = 0; DO=1 1478 dns_rdlength_begin(&towire); CH; 1479 dns_u16_to_wire(&towire, dns_opt_update_lease); CH; // OPTION-CODE 1480 dns_edns0_option_begin(&towire); CH; // OPTION-LENGTH 1481 if (removing) { 1482 // If we are removing the record, lease time should be zero. Key_lease_time can be nonzero, but we 1483 // aren't currently offering a way to do that in the server. Nevertheless, we send a key lease time. 1484 dns_u32_to_wire(&towire, 0); CH; 1485 dns_u32_to_wire(&towire, update_key_lease_time); CH; 1486 } else { 1487 dns_u32_to_wire(&towire, update_lease_time); CH; // LEASE (e.g. 1 hour) 1488 dns_u32_to_wire(&towire, update_key_lease_time); CH; // KEY-LEASE (7 days) 1489 } 1490 dns_edns0_option_end(&towire); CH; // Now we know OPTION-LENGTH 1491 dns_rdlength_end(&towire); CH; 1492 INCREMENT(message->arcount); 1493 1494 // The signature must be computed before counting the signature RR in the header counts. 1495 dns_sig0_signature_to_wire(&towire, 1496 client->key, key_tag, &p_host_name, chosen_hostname, zone_name, srp_timenow()); CH; 1497 INCREMENT(message->arcount); 1498 *p_length = towire.p - (uint8_t *)message; 1499 1500 if (conflict_hostname != NULL) { 1501 free(conflict_hostname); 1502 } 1503 return message; 1504 1505 fail: 1506 if (conflict_hostname != NULL) { 1507 free(conflict_hostname); 1508 } 1509 1510 if (towire.error) { 1511 ERROR("Ran out of message space at srp-client.c:%d (%d, %d)", 1512 line, towire.line, towire.outer_line); 1513 } 1514 if (client->active_update != NULL) { 1515 update_finalize(client->active_update); 1516 client->active_update = NULL; 1517 } 1518 if (in_wire == NULL && message != NULL) { 1519 free(message); 1520 } 1521 return NULL; 1522 } 1523 1524 // Send SRP updates for host records that have changed. 1525 static int 1526 do_srp_update(client_state_t *client, bool definite, bool *did_something) 1527 { 1528 int err; 1529 service_addr_t *server; 1530 1531 // Cancel any ongoing active update. 1532 if (!definite && client->active_update != NULL && client->registration_serial == client->active_update->serial) { 1533 bool server_changed = true; 1534 for (server = servers; server != NULL; server = server->next) { 1535 if (server == client->active_update->server) { 1536 server_changed = false; 1537 } 1538 } 1539 if (client->active_update->interface_serial == interface_serial && !server_changed) { 1540 INFO("addresses to register are the same; server is the same."); 1541 return kDNSServiceErr_NoError; 1542 } 1543 } 1544 1545 // At this point we're definitely doing something. 1546 if (did_something) { 1547 *did_something = true; 1548 } 1549 1550 // Get rid of the previous update, if any. 1551 if (client->active_update != NULL) { 1552 update_finalize(client->active_update); 1553 client->active_update = NULL; 1554 } 1555 1556 // Make an update context. 1557 update_context_t *active_update = calloc(1, sizeof(*active_update)); 1558 if (active_update == NULL) { 1559 err = kDNSServiceErr_NoMemory; 1560 } else { 1561 // If possible, use the server we used last time. 1562 active_update->client = client; 1563 sync_from_stable_storage(active_update); 1564 if (active_update->server == NULL) { 1565 active_update->server = servers; 1566 } 1567 active_update->serial = client->registration_serial; 1568 active_update->message = NULL; 1569 active_update->message_length = 0; 1570 active_update->lease_time = client->lease_time; 1571 active_update->key_lease_time = client->key_lease_time; 1572 err = srp_make_udp_context(client->os_context, &active_update->udp_context, udp_response, active_update); 1573 1574 if (err == kDNSServiceErr_NoError) { 1575 // XXX use some random jitter on these times. 1576 active_update->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 1577 active_update->next_attempt_time = INITIAL_NEXT_ATTEMPT_TIME; 1578 err = srp_set_wakeup(client->os_context, active_update->udp_context, srp_random16() % 1023, udp_retransmit); 1579 } 1580 } 1581 client->active_update = active_update; 1582 return err; 1583 } 1584 1585 // Deregister all existing registrations. 1586 int 1587 srp_deregister(void *os_context) 1588 { 1589 reg_state_t *rp; 1590 bool something_to_deregister = false; 1591 client_state_t *client; 1592 1593 for (client = clients; client; client = client->next) { 1594 if (client->os_context == os_context) { 1595 break; 1596 } 1597 } 1598 if (client == NULL) { 1599 return kDNSServiceErr_Invalid; 1600 } 1601 1602 if (client->active_update == NULL) { 1603 INFO("no active update."); 1604 return kDNSServiceErr_NoSuchRecord; 1605 } 1606 1607 // See if there are any registrations that have succeeded. 1608 for (rp = client->registrations; rp; rp = rp->next) { 1609 if (rp->serial <= client->active_update->serial && rp->succeeded) { 1610 something_to_deregister = true; 1611 } 1612 } 1613 1614 // If so, start a deregistration update; otherwise return NoSuchRecord. 1615 if (something_to_deregister) { 1616 if (client->active_update->message) { 1617 free(client->active_update->message); 1618 client->active_update->message = NULL; 1619 } 1620 client->active_update->removing = true; 1621 client->active_update->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 1622 client->active_update->next_attempt_time = INITIAL_NEXT_ATTEMPT_TIME; 1623 udp_retransmit(client->active_update); 1624 return kDNSServiceErr_NoError; 1625 } else { 1626 return kDNSServiceErr_NoSuchRecord; 1627 } 1628 } 1629 1630 // Deregister a specific registration 1631 int 1632 srp_deregister_instance(DNSServiceRef sdRef) 1633 { 1634 client_state_t *client; 1635 reg_state_t *rp; 1636 1637 // We only expect to find one match. 1638 for (client = clients; client; client = client->next) { 1639 for (rp = client->registrations; rp; rp = rp->next) { 1640 if (rp == sdRef) { 1641 goto found; 1642 } 1643 } 1644 } 1645 return kDNSServiceErr_NoSuchRecord; 1646 found: 1647 rp->removing = true; 1648 if (client->active_update != NULL) { 1649 if (client->active_update->message) { 1650 free(client->active_update->message); 1651 client->active_update->message = NULL; 1652 } 1653 client->active_update->next_retransmission_time = INITIAL_NEXT_RETRANSMISSION_TIME; 1654 client->active_update->next_attempt_time = INITIAL_NEXT_ATTEMPT_TIME; 1655 udp_retransmit(client->active_update); 1656 } 1657 return kDNSServiceErr_NoError; 1658 } 1659 1660 #ifdef THREAD_DEVKIT_ADK 1661 uint32_t 1662 srp_timenow(void) 1663 { 1664 return 0; 1665 } 1666 #endif // THREAD_DEVKIT_ADK 1667 1668 // Local Variables: 1669 // mode: C 1670 // tab-width: 4 1671 // c-file-style: "bsd" 1672 // c-basic-offset: 4 1673 // fill-column: 108 1674 // indent-tabs-mode: nil 1675 // End: 1676