Annotation of embedaddon/dhcp/omapip/protocol.c, revision 1.1
1.1 ! misho 1: /* protocol.c
! 2:
! 3: Functions supporting the object management protocol... */
! 4:
! 5: /*
! 6: * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
! 7: * Copyright (c) 1999-2003 by Internet Software Consortium
! 8: *
! 9: * Permission to use, copy, modify, and distribute this software for any
! 10: * purpose with or without fee is hereby granted, provided that the above
! 11: * copyright notice and this permission notice appear in all copies.
! 12: *
! 13: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
! 14: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 15: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
! 16: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 17: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 18: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 19: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 20: *
! 21: * Internet Systems Consortium, Inc.
! 22: * 950 Charter Street
! 23: * Redwood City, CA 94063
! 24: * <info@isc.org>
! 25: * https://www.isc.org/
! 26: *
! 27: * This software has been written for Internet Systems Consortium
! 28: * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
! 29: * To learn more about Internet Systems Consortium, see
! 30: * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
! 31: * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
! 32: * ``http://www.nominum.com''.
! 33: */
! 34:
! 35: #include "dhcpd.h"
! 36:
! 37: #include <omapip/omapip_p.h>
! 38:
! 39: OMAPI_OBJECT_ALLOC (omapi_protocol, omapi_protocol_object_t,
! 40: omapi_type_protocol)
! 41: OMAPI_OBJECT_ALLOC (omapi_protocol_listener, omapi_protocol_listener_object_t,
! 42: omapi_type_protocol_listener)
! 43:
! 44: isc_result_t omapi_protocol_connect (omapi_object_t *h,
! 45: const char *server_name,
! 46: unsigned port,
! 47: omapi_object_t *a)
! 48: {
! 49: isc_result_t rstatus, status;
! 50: omapi_protocol_object_t *obj;
! 51:
! 52: #ifdef DEBUG_PROTOCOL
! 53: log_debug ("omapi_protocol_connect(%s port=%d)", server_name, port);
! 54: #endif
! 55:
! 56: obj = (omapi_protocol_object_t *)0;
! 57: status = omapi_protocol_allocate (&obj, MDL);
! 58: if (status != ISC_R_SUCCESS)
! 59: return status;
! 60:
! 61: rstatus = omapi_connect ((omapi_object_t *)obj, server_name, port);
! 62: if (rstatus != ISC_R_SUCCESS && rstatus != ISC_R_INCOMPLETE) {
! 63: omapi_protocol_dereference (&obj, MDL);
! 64: return rstatus;
! 65: }
! 66: status = omapi_object_reference (&h -> outer,
! 67: (omapi_object_t *)obj, MDL);
! 68: if (status != ISC_R_SUCCESS) {
! 69: omapi_protocol_dereference (&obj, MDL);
! 70: return status;
! 71: }
! 72: status = omapi_object_reference (&obj -> inner, h, MDL);
! 73: if (status != ISC_R_SUCCESS) {
! 74: omapi_protocol_dereference (&obj, MDL);
! 75: return status;
! 76: }
! 77:
! 78: /* If we were passed a default authenticator, store it now. We'll
! 79: open it once we're connected. */
! 80: if (a) {
! 81: obj -> default_auth =
! 82: dmalloc (sizeof(omapi_remote_auth_t), MDL);
! 83: if (!obj -> default_auth) {
! 84: omapi_protocol_dereference (&obj, MDL);
! 85: return ISC_R_NOMEMORY;
! 86: }
! 87:
! 88: obj -> default_auth -> next = (omapi_remote_auth_t *)0;
! 89: status = omapi_object_reference (&obj -> default_auth -> a,
! 90: a, MDL);
! 91: if (status != ISC_R_SUCCESS) {
! 92: dfree (obj -> default_auth, MDL);
! 93: omapi_protocol_dereference (&obj, MDL);
! 94: return status;
! 95: }
! 96:
! 97: obj -> insecure = 0;
! 98: rstatus = ISC_R_INCOMPLETE;
! 99: } else {
! 100: obj -> insecure = 1;
! 101: #if 0
! 102: status = ISC_R_SUCCESS;
! 103: #endif
! 104: }
! 105:
! 106: omapi_protocol_dereference (&obj, MDL);
! 107: return rstatus;
! 108: }
! 109:
! 110: /* Send the protocol introduction message. */
! 111: isc_result_t omapi_protocol_send_intro (omapi_object_t *h,
! 112: unsigned ver,
! 113: unsigned hsize)
! 114: {
! 115: isc_result_t status;
! 116: omapi_protocol_object_t *p;
! 117:
! 118: #ifdef DEBUG_PROTOCOL
! 119: log_debug ("omapi_protocol_send_intro()");
! 120: #endif
! 121:
! 122: if (h -> type != omapi_type_protocol)
! 123: return ISC_R_INVALIDARG;
! 124: p = (omapi_protocol_object_t *)h;
! 125:
! 126: if (!h -> outer || h -> outer -> type != omapi_type_connection)
! 127: return ISC_R_NOTCONNECTED;
! 128:
! 129: status = omapi_connection_put_uint32 (h -> outer, ver);
! 130: if (status != ISC_R_SUCCESS)
! 131: return status;
! 132:
! 133: status = omapi_connection_put_uint32 (h -> outer, hsize);
! 134:
! 135: if (status != ISC_R_SUCCESS)
! 136: return status;
! 137:
! 138: /* Require the other end to send an intro - this kicks off the
! 139: protocol input state machine. */
! 140: p -> state = omapi_protocol_intro_wait;
! 141: status = omapi_connection_require (h -> outer, 8);
! 142: if (status != ISC_R_SUCCESS && status != ISC_R_NOTYET)
! 143: return status;
! 144:
! 145: /* Make up an initial transaction ID for this connection. */
! 146: p -> next_xid = random ();
! 147: return ISC_R_SUCCESS;
! 148: }
! 149:
! 150: #ifdef DEBUG_PROTOCOL
! 151: extern const char *omapi_message_op_name(int);
! 152: #endif /* DEBUG_PROTOCOL */
! 153:
! 154: isc_result_t omapi_protocol_send_message (omapi_object_t *po,
! 155: omapi_object_t *id,
! 156: omapi_object_t *mo,
! 157: omapi_object_t *omo)
! 158: {
! 159: omapi_protocol_object_t *p;
! 160: omapi_object_t *c;
! 161: omapi_message_object_t *m, *om;
! 162: omapi_remote_auth_t *ra;
! 163: omapi_value_t *signature;
! 164: isc_result_t status;
! 165: unsigned auth_len;
! 166:
! 167: if (po -> type != omapi_type_protocol ||
! 168: !po -> outer || po -> outer -> type != omapi_type_connection ||
! 169: mo -> type != omapi_type_message)
! 170: return ISC_R_INVALIDARG;
! 171: if (omo && omo -> type != omapi_type_message)
! 172: return ISC_R_INVALIDARG;
! 173: p = (omapi_protocol_object_t *)po;
! 174: c = (omapi_object_t *)(po -> outer);
! 175: m = (omapi_message_object_t *)mo;
! 176: om = (omapi_message_object_t *)omo;
! 177:
! 178: #ifdef DEBUG_PROTOCOL
! 179: log_debug ("omapi_protocol_send_message(): "
! 180: "op=%s handle=%#lx id=%#lx rid=%#lx",
! 181: omapi_message_op_name (m->op),
! 182: (long)(m -> object ? m -> object -> handle : m -> handle),
! 183: (long)p -> next_xid, (long)m -> rid);
! 184: #endif
! 185:
! 186: /* Find the authid to use for this message. */
! 187: if (id) {
! 188: for (ra = p -> remote_auth_list; ra; ra = ra -> next) {
! 189: if (ra -> a == id) {
! 190: break;
! 191: }
! 192: }
! 193:
! 194: if (!ra)
! 195: return ISC_R_KEY_UNKNOWN;
! 196: } else if (p -> remote_auth_list) {
! 197: ra = p -> default_auth;
! 198: } else {
! 199: ra = (omapi_remote_auth_t *)0;
! 200: }
! 201:
! 202: if (ra) {
! 203: m -> authid = ra -> remote_handle;
! 204: status = omapi_object_reference (&m -> id_object,
! 205: ra -> a, MDL);
! 206: if (status != ISC_R_SUCCESS)
! 207: return status;
! 208: }
! 209:
! 210: /* Write the ID of the authentication key we're using. */
! 211: status = omapi_connection_put_uint32 (c, ra ? ra -> remote_handle : 0);
! 212: if (status != ISC_R_SUCCESS) {
! 213: omapi_disconnect (c, 1);
! 214: return status;
! 215: }
! 216:
! 217: /* Activate the authentication key on the connection. */
! 218: auth_len = 0;
! 219: if (ra) {
! 220: status = omapi_set_object_value (c, (omapi_object_t *)0,
! 221: "output-authenticator",
! 222: ra -> a);
! 223: if (status != ISC_R_SUCCESS) {
! 224: omapi_disconnect (c, 1);
! 225: return status;
! 226: }
! 227:
! 228: status = omapi_connection_output_auth_length (c, &auth_len);
! 229: if (status != ISC_R_SUCCESS) {
! 230: omapi_disconnect (c, 1);
! 231: return status;
! 232: }
! 233: }
! 234:
! 235: /* Write the authenticator length */
! 236: status = omapi_connection_put_uint32 (c, auth_len);
! 237: if (status != ISC_R_SUCCESS) {
! 238: omapi_disconnect (c, 1);
! 239: return status;
! 240: }
! 241:
! 242: /* Write the opcode. */
! 243: status = omapi_connection_put_uint32 (c, m -> op);
! 244: if (status != ISC_R_SUCCESS) {
! 245: omapi_disconnect (c, 1);
! 246: return status;
! 247: }
! 248:
! 249: /* Write the handle. If we've been given an explicit handle, use
! 250: that. Otherwise, use the handle of the object we're sending.
! 251: The caller is responsible for arranging for one of these handles
! 252: to be set (or not). */
! 253: status = omapi_connection_put_uint32 (c, (m -> h
! 254: ? m -> h
! 255: : (m -> object
! 256: ? m -> object -> handle
! 257: : 0)));
! 258: if (status != ISC_R_SUCCESS) {
! 259: omapi_disconnect (c, 1);
! 260: return status;
! 261: }
! 262:
! 263: /* Set and write the transaction ID. */
! 264: m -> id = p -> next_xid++;
! 265: status = omapi_connection_put_uint32 (c, m -> id);
! 266: if (status != ISC_R_SUCCESS) {
! 267: omapi_disconnect (c, 1);
! 268: return status;
! 269: }
! 270:
! 271: /* Write the transaction ID of the message to which this is a
! 272: response, if there is such a message. */
! 273: status = omapi_connection_put_uint32 (c, om ? om -> id : m -> rid);
! 274: if (status != ISC_R_SUCCESS) {
! 275: omapi_disconnect (c, 1);
! 276: return status;
! 277: }
! 278:
! 279: /* Stuff out the name/value pairs specific to this message. */
! 280: status = omapi_stuff_values (c, id, (omapi_object_t *)m);
! 281: if (status != ISC_R_SUCCESS) {
! 282: omapi_disconnect (c, 1);
! 283: return status;
! 284: }
! 285:
! 286: /* Write the zero-length name that terminates the list of name/value
! 287: pairs specific to the message. */
! 288: status = omapi_connection_put_uint16 (c, 0);
! 289: if (status != ISC_R_SUCCESS) {
! 290: omapi_disconnect (c, 1);
! 291: return status;
! 292: }
! 293:
! 294: /* Stuff out all the published name/value pairs in the object that's
! 295: being sent in the message, if there is one. */
! 296: if (m -> object) {
! 297: status = omapi_stuff_values (c, id, m -> object);
! 298: if (status != ISC_R_SUCCESS) {
! 299: omapi_disconnect (c, 1);
! 300: return status;
! 301: }
! 302: }
! 303:
! 304: /* Write the zero-length name that terminates the list of name/value
! 305: pairs for the associated object. */
! 306: status = omapi_connection_put_uint16 (c, 0);
! 307: if (status != ISC_R_SUCCESS) {
! 308: omapi_disconnect (c, 1);
! 309: return status;
! 310: }
! 311:
! 312: if (ra) {
! 313: /* Calculate the message signature. */
! 314: signature = (omapi_value_t *)0;
! 315: status = omapi_get_value_str (c, (omapi_object_t *)0,
! 316: "output-signature", &signature);
! 317: if (status != ISC_R_SUCCESS) {
! 318: omapi_disconnect (c, 1);
! 319: return status;
! 320: }
! 321:
! 322: /* Write the authenticator... */
! 323: status = (omapi_connection_copyin
! 324: (c, signature -> value -> u.buffer.value,
! 325: signature -> value -> u.buffer.len));
! 326: omapi_value_dereference (&signature, MDL);
! 327: if (status != ISC_R_SUCCESS) {
! 328: omapi_disconnect (c, 1);
! 329: return status;
! 330: }
! 331:
! 332: /* Dectivate the authentication key on the connection. */
! 333: status = omapi_set_value_str (c, (omapi_object_t *)0,
! 334: "output-authenticator",
! 335: (omapi_typed_data_t *)0);
! 336: if (status != ISC_R_SUCCESS) {
! 337: omapi_disconnect (c, 1);
! 338: return status;
! 339: }
! 340: }
! 341:
! 342: if (!omo) {
! 343: omapi_protocol_reference (&m -> protocol_object, p, MDL);
! 344: }
! 345: return ISC_R_SUCCESS;
! 346: }
! 347:
! 348:
! 349: isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
! 350: const char *name, va_list ap)
! 351: {
! 352: isc_result_t status;
! 353: omapi_protocol_object_t *p;
! 354: omapi_object_t *c;
! 355: omapi_message_object_t *m;
! 356: omapi_value_t *signature;
! 357: u_int16_t nlen;
! 358: u_int32_t vlen;
! 359: u_int32_t th;
! 360: #if defined (DEBUG_MEMORY_LEAKAGE)
! 361: unsigned long previous_outstanding = 0xDEADBEEF;
! 362: unsigned long connect_outstanding = 0xDEADBEEF;
! 363: #endif
! 364:
! 365: if (h -> type != omapi_type_protocol) {
! 366: /* XXX shouldn't happen. Put an assert here? */
! 367: return ISC_R_UNEXPECTED;
! 368: }
! 369: p = (omapi_protocol_object_t *)h;
! 370:
! 371: if (!strcmp (name, "connect")) {
! 372: #if defined (DEBUG_MEMORY_LEAKAGE)
! 373: connect_outstanding = dmalloc_outstanding;
! 374: #endif
! 375: /* Send the introductory message. */
! 376: status = omapi_protocol_send_intro
! 377: (h, OMAPI_PROTOCOL_VERSION,
! 378: sizeof (omapi_protocol_header_t));
! 379: if (status != ISC_R_SUCCESS) {
! 380: omapi_disconnect (p -> outer, 1);
! 381: return status;
! 382: }
! 383: return ISC_R_SUCCESS;
! 384: }
! 385:
! 386: /* Should only receive these when opening the initial authenticator. */
! 387: if (!strcmp (name, "status")) {
! 388: status = va_arg (ap, isc_result_t);
! 389: if (status != ISC_R_SUCCESS) {
! 390: omapi_signal_in (h -> inner, "status", status,
! 391: (omapi_object_t *)0);
! 392: omapi_disconnect (p -> outer, 1);
! 393: return status;
! 394: } else {
! 395: return omapi_signal_in (h -> inner, "ready");
! 396: }
! 397: }
! 398:
! 399: /* If we get a disconnect, dump memory usage. */
! 400: if (!strcmp (name, "disconnect")) {
! 401: #if defined (DEBUG_MEMORY_LEAKAGE)
! 402: if (connect_outstanding != 0xDEADBEEF) {
! 403: log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
! 404: dmalloc_generation,
! 405: dmalloc_outstanding - previous_outstanding,
! 406: dmalloc_outstanding, dmalloc_longterm, " long-term");
! 407: }
! 408: #endif
! 409: #if defined (DEBUG_MEMORY_LEAKAGE)
! 410: dmalloc_dump_outstanding ();
! 411: #endif
! 412: #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
! 413: dump_rc_history (h);
! 414: #endif
! 415: for (m = omapi_registered_messages; m; m = m -> next) {
! 416: if (m -> protocol_object == p) {
! 417: if (m -> object)
! 418: omapi_signal (m -> object, "disconnect");
! 419: }
! 420: }
! 421:
! 422: /* XXX */
! 423: return ISC_R_SUCCESS;
! 424: }
! 425:
! 426: /* Not a signal we recognize? */
! 427: if (strcmp (name, "ready")) {
! 428: if (p -> inner && p -> inner -> type -> signal_handler)
! 429: return (*(p -> inner -> type -> signal_handler)) (h,
! 430: name,
! 431: ap);
! 432: return ISC_R_NOTFOUND;
! 433: }
! 434:
! 435: if (!p -> outer || p -> outer -> type != omapi_type_connection)
! 436: return ISC_R_INVALIDARG;
! 437: c = p -> outer;
! 438:
! 439: /* We get here because we requested that we be woken up after
! 440: some number of bytes were read, and that number of bytes
! 441: has in fact been read. */
! 442: switch (p -> state) {
! 443: case omapi_protocol_intro_wait:
! 444: /* Get protocol version and header size in network
! 445: byte order. */
! 446: omapi_connection_get_uint32 (c, &p -> protocol_version);
! 447: omapi_connection_get_uint32 (c, &p -> header_size);
! 448:
! 449: /* We currently only support the current protocol version. */
! 450: if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
! 451: omapi_disconnect (c, 1);
! 452: return ISC_R_VERSIONMISMATCH;
! 453: }
! 454:
! 455: if (p -> header_size < sizeof (omapi_protocol_header_t)) {
! 456: omapi_disconnect (c, 1);
! 457: return ISC_R_PROTOCOLERROR;
! 458: }
! 459:
! 460: if (p -> default_auth) {
! 461: status = omapi_protocol_send_open
! 462: (h, (omapi_object_t *)0, "authenticator",
! 463: p -> default_auth -> a,
! 464: OMAPI_NOTIFY_PROTOCOL);
! 465: if (status != ISC_R_SUCCESS) {
! 466: omapi_disconnect (c, 1);
! 467: return status;
! 468: }
! 469: } else {
! 470: status = omapi_signal_in (h -> inner, "ready");
! 471: }
! 472:
! 473: to_header_wait:
! 474: /* The next thing we're expecting is a message header. */
! 475: p -> state = omapi_protocol_header_wait;
! 476:
! 477: /* Register a need for the number of bytes in a
! 478: header, and if we already have that many, process
! 479: them immediately. */
! 480: if ((omapi_connection_require (c, p -> header_size)) !=
! 481: ISC_R_SUCCESS)
! 482: break;
! 483: /* If we already have the data, fall through. */
! 484:
! 485: case omapi_protocol_header_wait:
! 486: #if defined (DEBUG_MEMORY_LEAKAGE)
! 487: if (previous_outstanding != 0xDEADBEEF) {
! 488: log_info ("%s %ld: %ld new, %ld outstanding, %ld%s",
! 489: "generation", dmalloc_generation,
! 490: dmalloc_outstanding - previous_outstanding,
! 491: dmalloc_outstanding, dmalloc_longterm,
! 492: " long-term");
! 493: #endif
! 494: #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
! 495: dmalloc_dump_outstanding ();
! 496: #endif
! 497: #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
! 498: dump_rc_history (h);
! 499: #endif
! 500: #if defined (DEBUG_MEMORY_LEAKAGE)
! 501: }
! 502: previous_outstanding = dmalloc_outstanding;
! 503: #endif
! 504: status = omapi_message_new ((omapi_object_t **)&p -> message,
! 505: MDL);
! 506: if (status != ISC_R_SUCCESS) {
! 507: omapi_disconnect (c, 1);
! 508: return status;
! 509: }
! 510:
! 511: p -> verify_result = ISC_R_SUCCESS;
! 512:
! 513: /* Swap in the header... */
! 514: omapi_connection_get_uint32 (c, &p -> message -> authid);
! 515:
! 516: /* Bind the authenticator to the message object. */
! 517: if (p -> message -> authid) {
! 518: status = (omapi_protocol_lookup_auth
! 519: (&p -> message -> id_object, h,
! 520: p -> message -> authid));
! 521: if (status != ISC_R_SUCCESS)
! 522: p -> verify_result = status;
! 523:
! 524: /* Activate the authentication key. */
! 525: status = omapi_set_object_value
! 526: (c, (omapi_object_t *)0, "input-authenticator",
! 527: p -> message -> id_object);
! 528: if (status != ISC_R_SUCCESS) {
! 529: omapi_disconnect (c, 1);
! 530: return status;
! 531: }
! 532: }
! 533:
! 534: omapi_connection_get_uint32 (c, &p -> message -> authlen);
! 535: omapi_connection_get_uint32 (c, &p -> message -> op);
! 536: omapi_connection_get_uint32 (c, &th);
! 537: p -> message -> h = th;
! 538: omapi_connection_get_uint32 (c, &p -> message -> id);
! 539: omapi_connection_get_uint32 (c, &p -> message -> rid);
! 540:
! 541: /* If there was any extra header data, skip over it. */
! 542: if (p -> header_size > sizeof (omapi_protocol_header_t)) {
! 543: omapi_connection_copyout
! 544: (0, c, (p -> header_size -
! 545: sizeof (omapi_protocol_header_t)));
! 546: }
! 547:
! 548: /* XXX must compute partial signature across the
! 549: XXX preceding bytes. Also, if authenticator
! 550: specifies encryption as well as signing, we may
! 551: have to decrypt the data on the way in. */
! 552:
! 553: /* First we read in message-specific values, then object
! 554: values. */
! 555: p -> reading_message_values = 1;
! 556:
! 557: need_name_length:
! 558: /* The next thing we're expecting is length of the
! 559: first name. */
! 560: p -> state = omapi_protocol_name_length_wait;
! 561:
! 562: /* Wait for a 16-bit length. */
! 563: if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
! 564: break;
! 565: /* If it's already here, fall through. */
! 566:
! 567: case omapi_protocol_name_length_wait:
! 568: omapi_connection_get_uint16 (c, &nlen);
! 569: /* A zero-length name means that we're done reading name+value
! 570: pairs. */
! 571: if (nlen == 0) {
! 572: /* If we've already read in the object, we are
! 573: done reading the message, but if we've just
! 574: finished reading in the values associated
! 575: with the message, we need to read the
! 576: object. */
! 577: if (p -> reading_message_values) {
! 578: p -> reading_message_values = 0;
! 579: goto need_name_length;
! 580: }
! 581:
! 582: /* If the authenticator length is zero, there's no
! 583: signature to read in, so go straight to processing
! 584: the message. */
! 585: if (p -> message -> authlen == 0)
! 586: goto message_done;
! 587:
! 588: /* The next thing we're expecting is the
! 589: message signature. */
! 590: p -> state = omapi_protocol_signature_wait;
! 591:
! 592: /* Wait for the number of bytes specified for
! 593: the authenticator. If we already have it,
! 594: go read it in. */
! 595: if (omapi_connection_require
! 596: (c, p -> message -> authlen) == ISC_R_SUCCESS)
! 597: goto signature_wait;
! 598: break;
! 599: }
! 600:
! 601: /* Allocate a buffer for the name. */
! 602: status = (omapi_data_string_new (&p -> name, nlen, MDL));
! 603: if (status != ISC_R_SUCCESS) {
! 604: omapi_disconnect (c, 1);
! 605: return ISC_R_NOMEMORY;
! 606: }
! 607: p -> state = omapi_protocol_name_wait;
! 608: if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
! 609: break;
! 610: /* If it's already here, fall through. */
! 611:
! 612: case omapi_protocol_name_wait:
! 613: omapi_connection_copyout (p -> name -> value, c,
! 614: p -> name -> len);
! 615: /* Wait for a 32-bit length. */
! 616: p -> state = omapi_protocol_value_length_wait;
! 617: if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
! 618: break;
! 619: /* If it's already here, fall through. */
! 620:
! 621: case omapi_protocol_value_length_wait:
! 622: omapi_connection_get_uint32 (c, &vlen);
! 623:
! 624: /* Zero-length values are allowed - if we get one, we
! 625: don't have to read any data for the value - just
! 626: get the next one, if there is a next one. */
! 627: if (!vlen)
! 628: goto insert_new_value;
! 629:
! 630: status = omapi_typed_data_new (MDL, &p -> value,
! 631: omapi_datatype_data,
! 632: vlen);
! 633: if (status != ISC_R_SUCCESS) {
! 634: omapi_disconnect (c, 1);
! 635: return ISC_R_NOMEMORY;
! 636: }
! 637:
! 638: p -> state = omapi_protocol_value_wait;
! 639: if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
! 640: break;
! 641: /* If it's already here, fall through. */
! 642:
! 643: case omapi_protocol_value_wait:
! 644: omapi_connection_copyout (p -> value -> u.buffer.value, c,
! 645: p -> value -> u.buffer.len);
! 646:
! 647: insert_new_value:
! 648: if (p -> reading_message_values) {
! 649: status = (omapi_set_value
! 650: ((omapi_object_t *)p -> message,
! 651: p -> message -> id_object,
! 652: p -> name, p -> value));
! 653: } else {
! 654: if (!p -> message -> object) {
! 655: /* We need a generic object to hang off of the
! 656: incoming message. */
! 657: status = (omapi_generic_new
! 658: (&p -> message -> object, MDL));
! 659: if (status != ISC_R_SUCCESS) {
! 660: omapi_disconnect (c, 1);
! 661: return status;
! 662: }
! 663: }
! 664: status = (omapi_set_value
! 665: ((omapi_object_t *)p -> message -> object,
! 666: p -> message -> id_object,
! 667: p -> name, p -> value));
! 668: }
! 669: if (status != ISC_R_SUCCESS) {
! 670: omapi_disconnect (c, 1);
! 671: return status;
! 672: }
! 673: omapi_data_string_dereference (&p -> name, MDL);
! 674: if (p -> value)
! 675: omapi_typed_data_dereference (&p -> value, MDL);
! 676: goto need_name_length;
! 677:
! 678: signature_wait:
! 679: case omapi_protocol_signature_wait:
! 680: if (p -> message -> id_object) {
! 681: /* Compute the signature of the message. */
! 682: signature = (omapi_value_t *)0;
! 683: status = omapi_get_value_str (c, (omapi_object_t *)0,
! 684: "input-signature",
! 685: &signature);
! 686: if (status != ISC_R_SUCCESS) {
! 687: omapi_disconnect (c, 1);
! 688: return status;
! 689: }
! 690:
! 691: /* Disable the authentication key on the connection. */
! 692: status = omapi_set_value_str (c, (omapi_object_t *)0,
! 693: "input-authenticator",
! 694: (omapi_typed_data_t *)0);
! 695: if (status != ISC_R_SUCCESS) {
! 696: omapi_value_dereference (&signature, MDL);
! 697: omapi_disconnect (c, 1);
! 698: return status;
! 699: }
! 700: }
! 701:
! 702: /* Read the authenticator. */
! 703: status = omapi_typed_data_new (MDL,
! 704: &p -> message -> authenticator,
! 705: omapi_datatype_data,
! 706: p -> message -> authlen);
! 707:
! 708: if (status != ISC_R_SUCCESS) {
! 709: omapi_value_dereference (&signature, MDL);
! 710: omapi_disconnect (c, 1);
! 711: return ISC_R_NOMEMORY;
! 712: }
! 713: omapi_connection_copyout
! 714: (p -> message -> authenticator -> u.buffer.value, c,
! 715: p -> message -> authlen);
! 716:
! 717: /* Verify the signature. */
! 718: if (p -> message -> id_object &&
! 719: ((signature -> value -> u.buffer.len !=
! 720: p -> message -> authlen) ||
! 721: (memcmp (signature -> value -> u.buffer.value,
! 722: p -> message -> authenticator -> u.buffer.value,
! 723: p -> message -> authlen) != 0))) {
! 724: /* Invalid signature. */
! 725: p -> verify_result = ISC_R_INVALIDKEY;
! 726: }
! 727:
! 728: omapi_value_dereference (&signature, MDL);
! 729:
! 730: /* Process the message. */
! 731: message_done:
! 732: if (p -> verify_result != ISC_R_SUCCESS) {
! 733: status = omapi_protocol_send_status
! 734: (h, (omapi_object_t *)0, p -> verify_result,
! 735: p -> message -> id, (char *)0);
! 736: } else {
! 737: status = omapi_message_process
! 738: ((omapi_object_t *)p -> message, h);
! 739: }
! 740: if (status != ISC_R_SUCCESS) {
! 741: omapi_disconnect (c, 1);
! 742: return ISC_R_NOMEMORY;
! 743: }
! 744:
! 745: omapi_message_dereference (&p -> message, MDL);
! 746: #if defined (DEBUG_MEMORY_LEAKAGE)
! 747: log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
! 748: dmalloc_generation,
! 749: dmalloc_outstanding - previous_outstanding,
! 750: dmalloc_outstanding, dmalloc_longterm, " long-term");
! 751: #endif
! 752: #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
! 753: dmalloc_dump_outstanding ();
! 754: #endif
! 755: #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
! 756: dump_rc_history (h);
! 757: #endif
! 758: #if defined (DEBUG_MEMORY_LEAKAGE)
! 759: previous_outstanding = 0xDEADBEEF;
! 760: #endif
! 761: /* Now wait for the next message. */
! 762: goto to_header_wait;
! 763:
! 764: default:
! 765: /* XXX should never get here. Assertion? */
! 766: break;
! 767: }
! 768: return ISC_R_SUCCESS;
! 769: }
! 770:
! 771: isc_result_t omapi_protocol_add_auth (omapi_object_t *po,
! 772: omapi_object_t *ao,
! 773: omapi_handle_t handle)
! 774: {
! 775: omapi_protocol_object_t *p;
! 776: omapi_remote_auth_t *r;
! 777: isc_result_t status;
! 778:
! 779: if (ao -> type != omapi_type_auth_key &&
! 780: (!ao -> inner || ao -> inner -> type != omapi_type_auth_key))
! 781: return ISC_R_INVALIDARG;
! 782:
! 783: if (po -> type != omapi_type_protocol)
! 784: return ISC_R_INVALIDARG;
! 785: p = (omapi_protocol_object_t *)po;
! 786:
! 787: #ifdef DEBUG_PROTOCOL
! 788: log_debug ("omapi_protocol_add_auth(name=%s)",
! 789: ((omapi_auth_key_t *)ao) -> name);
! 790: #endif
! 791:
! 792: if (p -> verify_auth) {
! 793: status = (p -> verify_auth) (po, (omapi_auth_key_t *)ao);
! 794: if (status != ISC_R_SUCCESS)
! 795: return status;
! 796: }
! 797:
! 798: /* If omapi_protocol_connect() was called with a default
! 799: authenticator, p -> default_auth will already be set,
! 800: but p -> remote_auth_list will not yet be initialized. */
! 801: if (p -> default_auth && !p -> remote_auth_list) {
! 802: if (p -> default_auth -> a != ao) {
! 803: /* Something just went horribly wrong. */
! 804: omapi_disconnect (p -> outer, 1);
! 805: return ISC_R_UNEXPECTED;
! 806: }
! 807:
! 808: p -> remote_auth_list = p -> default_auth;
! 809: p -> default_auth -> remote_handle = handle;
! 810:
! 811: return omapi_signal_in (p -> inner, "ready");
! 812: }
! 813:
! 814: r = dmalloc (sizeof(*r), MDL);
! 815: if (!r)
! 816: return ISC_R_NOMEMORY;
! 817:
! 818: status = omapi_object_reference (&r -> a, ao, MDL);
! 819: if (status != ISC_R_SUCCESS) {
! 820: dfree (r, MDL);
! 821: return status;
! 822: }
! 823:
! 824: r -> remote_handle = handle;
! 825: r -> next = p -> remote_auth_list;
! 826: p -> remote_auth_list = r;
! 827:
! 828: return ISC_R_SUCCESS;
! 829: }
! 830:
! 831: isc_result_t omapi_protocol_lookup_auth (omapi_object_t **a,
! 832: omapi_object_t *po,
! 833: omapi_handle_t handle)
! 834: {
! 835: omapi_protocol_object_t *p;
! 836: omapi_remote_auth_t *r;
! 837:
! 838: if (po -> type != omapi_type_protocol)
! 839: return ISC_R_INVALIDARG;
! 840: p = (omapi_protocol_object_t *)po;
! 841:
! 842: for (r = p -> remote_auth_list; r; r = r -> next)
! 843: if (r -> remote_handle == handle)
! 844: return omapi_object_reference (a, r -> a, MDL);
! 845:
! 846: return ISC_R_KEY_UNKNOWN;
! 847: }
! 848:
! 849: isc_result_t omapi_protocol_set_value (omapi_object_t *h,
! 850: omapi_object_t *id,
! 851: omapi_data_string_t *name,
! 852: omapi_typed_data_t *value)
! 853: {
! 854: omapi_protocol_object_t *p;
! 855: omapi_remote_auth_t *r;
! 856:
! 857: if (h -> type != omapi_type_protocol)
! 858: return ISC_R_INVALIDARG;
! 859: p = (omapi_protocol_object_t *)h;
! 860:
! 861: if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
! 862: if (value -> type != omapi_datatype_object)
! 863: return ISC_R_INVALIDARG;
! 864:
! 865: if (!value || !value -> u.object) {
! 866: p -> default_auth = (omapi_remote_auth_t *)0;
! 867: } else {
! 868: for (r = p -> remote_auth_list; r; r = r -> next)
! 869: if (r -> a == value -> u.object)
! 870: break;
! 871:
! 872: if (!r)
! 873: return ISC_R_KEY_UNKNOWN;
! 874:
! 875: p -> default_auth = r;
! 876: }
! 877:
! 878: return ISC_R_SUCCESS;
! 879: }
! 880:
! 881: if (h -> inner && h -> inner -> type -> set_value)
! 882: return (*(h -> inner -> type -> set_value))
! 883: (h -> inner, id, name, value);
! 884: return ISC_R_NOTFOUND;
! 885: }
! 886:
! 887: isc_result_t omapi_protocol_get_value (omapi_object_t *h,
! 888: omapi_object_t *id,
! 889: omapi_data_string_t *name,
! 890: omapi_value_t **value)
! 891: {
! 892: omapi_protocol_object_t *p;
! 893:
! 894: if (h -> type != omapi_type_protocol)
! 895: return ISC_R_INVALIDARG;
! 896: p = (omapi_protocol_object_t *)h;
! 897:
! 898: if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
! 899: if (!p -> default_auth)
! 900: return ISC_R_NOTFOUND;
! 901:
! 902: return omapi_make_object_value (value, name,
! 903: p -> default_auth -> a, MDL);
! 904: }
! 905:
! 906: if (h -> inner && h -> inner -> type -> get_value)
! 907: return (*(h -> inner -> type -> get_value))
! 908: (h -> inner, id, name, value);
! 909: return ISC_R_NOTFOUND;
! 910: }
! 911:
! 912: isc_result_t omapi_protocol_destroy (omapi_object_t *h,
! 913: const char *file, int line)
! 914: {
! 915: omapi_protocol_object_t *p;
! 916: if (h -> type != omapi_type_protocol)
! 917: return ISC_R_INVALIDARG;
! 918: p = (omapi_protocol_object_t *)h;
! 919: if (p -> message)
! 920: omapi_message_dereference (&p -> message, file, line);
! 921:
! 922: /* This will happen if: 1) A default authenticator is supplied to
! 923: omapi_protocol_connect(), and 2) something goes wrong before
! 924: the authenticator can be opened. */
! 925: if (p -> default_auth && !p -> remote_auth_list)
! 926: dfree (p -> default_auth, file, line);
! 927:
! 928: while (p -> remote_auth_list) {
! 929: omapi_remote_auth_t *r = p -> remote_auth_list -> next;
! 930: p -> remote_auth_list = r;
! 931: if (r) {
! 932: omapi_object_dereference (&r -> a, file, line);
! 933: dfree (r, file, line);
! 934: }
! 935: }
! 936: return ISC_R_SUCCESS;
! 937: }
! 938:
! 939: /* Write all the published values associated with the object through the
! 940: specified connection. */
! 941:
! 942: isc_result_t omapi_protocol_stuff_values (omapi_object_t *c,
! 943: omapi_object_t *id,
! 944: omapi_object_t *p)
! 945: {
! 946: if (p -> type != omapi_type_protocol)
! 947: return ISC_R_INVALIDARG;
! 948:
! 949: if (p -> inner && p -> inner -> type -> stuff_values)
! 950: return (*(p -> inner -> type -> stuff_values)) (c, id,
! 951: p -> inner);
! 952: return ISC_R_SUCCESS;
! 953: }
! 954:
! 955: /* Returns a boolean indicating whether this protocol requires that
! 956: messages be authenticated or not. */
! 957:
! 958: isc_boolean_t omapi_protocol_authenticated (omapi_object_t *h)
! 959: {
! 960: if (h -> type != omapi_type_protocol)
! 961: return isc_boolean_false;
! 962: if (((omapi_protocol_object_t *)h) -> insecure)
! 963: return isc_boolean_false;
! 964: else
! 965: return isc_boolean_true;
! 966: }
! 967:
! 968: /* Sets the address and authenticator verification callbacks. The handle
! 969: is to a listener object, not a protocol object. */
! 970:
! 971: isc_result_t omapi_protocol_configure_security (omapi_object_t *h,
! 972: isc_result_t (*verify_addr)
! 973: (omapi_object_t *,
! 974: omapi_addr_t *),
! 975: isc_result_t (*verify_auth)
! 976: (omapi_object_t *,
! 977: omapi_auth_key_t *))
! 978: {
! 979: omapi_protocol_listener_object_t *l;
! 980:
! 981: if (h -> outer && h -> outer -> type == omapi_type_protocol_listener)
! 982: h = h -> outer;
! 983:
! 984: if (h -> type != omapi_type_protocol_listener)
! 985: return ISC_R_INVALIDARG;
! 986: l = (omapi_protocol_listener_object_t *)h;
! 987:
! 988: l -> verify_auth = verify_auth;
! 989: l -> insecure = 0;
! 990:
! 991: return omapi_listener_configure_security (h -> outer, verify_addr);
! 992: }
! 993:
! 994:
! 995: /* Set up a listener for the omapi protocol. The handle stored points to
! 996: a listener object, not a protocol object. */
! 997:
! 998: isc_result_t omapi_protocol_listen (omapi_object_t *h,
! 999: unsigned port,
! 1000: int max)
! 1001: {
! 1002: isc_result_t status;
! 1003: omapi_protocol_listener_object_t *obj;
! 1004:
! 1005: obj = (omapi_protocol_listener_object_t *)0;
! 1006: status = omapi_protocol_listener_allocate (&obj, MDL);
! 1007: if (status != ISC_R_SUCCESS)
! 1008: return status;
! 1009:
! 1010: status = omapi_object_reference (&h -> outer,
! 1011: (omapi_object_t *)obj, MDL);
! 1012: if (status != ISC_R_SUCCESS) {
! 1013: omapi_protocol_listener_dereference (&obj, MDL);
! 1014: return status;
! 1015: }
! 1016: status = omapi_object_reference (&obj -> inner, h, MDL);
! 1017: if (status != ISC_R_SUCCESS) {
! 1018: omapi_protocol_listener_dereference (&obj, MDL);
! 1019: return status;
! 1020: }
! 1021:
! 1022: /* What a terrible default. */
! 1023: obj -> insecure = 1;
! 1024:
! 1025: status = omapi_listen ((omapi_object_t *)obj, port, max);
! 1026: omapi_protocol_listener_dereference (&obj, MDL);
! 1027: return status;
! 1028: }
! 1029:
! 1030: /* Signal handler for protocol listener - if we get a connect signal,
! 1031: create a new protocol connection, otherwise pass the signal down. */
! 1032:
! 1033: isc_result_t omapi_protocol_listener_signal (omapi_object_t *o,
! 1034: const char *name, va_list ap)
! 1035: {
! 1036: isc_result_t status;
! 1037: omapi_object_t *c;
! 1038: omapi_protocol_object_t *obj;
! 1039: omapi_protocol_listener_object_t *p;
! 1040:
! 1041: if (!o || o -> type != omapi_type_protocol_listener)
! 1042: return ISC_R_INVALIDARG;
! 1043: p = (omapi_protocol_listener_object_t *)o;
! 1044:
! 1045: /* Not a signal we recognize? */
! 1046: if (strcmp (name, "connect")) {
! 1047: if (p -> inner && p -> inner -> type -> signal_handler)
! 1048: return (*(p -> inner -> type -> signal_handler))
! 1049: (p -> inner, name, ap);
! 1050: return ISC_R_NOTFOUND;
! 1051: }
! 1052:
! 1053: c = va_arg (ap, omapi_object_t *);
! 1054: if (!c || c -> type != omapi_type_connection)
! 1055: return ISC_R_INVALIDARG;
! 1056:
! 1057: obj = (omapi_protocol_object_t *)0;
! 1058: status = omapi_protocol_allocate (&obj, MDL);
! 1059: if (status != ISC_R_SUCCESS)
! 1060: return status;
! 1061:
! 1062: obj -> verify_auth = p -> verify_auth;
! 1063: obj -> insecure = p -> insecure;
! 1064:
! 1065: status = omapi_object_reference (&obj -> outer, c, MDL);
! 1066: if (status != ISC_R_SUCCESS) {
! 1067: lose:
! 1068: omapi_protocol_dereference (&obj, MDL);
! 1069: omapi_disconnect (c, 1);
! 1070: return status;
! 1071: }
! 1072:
! 1073: status = omapi_object_reference (&c -> inner,
! 1074: (omapi_object_t *)obj, MDL);
! 1075: if (status != ISC_R_SUCCESS)
! 1076: goto lose;
! 1077:
! 1078: /* Send the introductory message. */
! 1079: status = omapi_protocol_send_intro ((omapi_object_t *)obj,
! 1080: OMAPI_PROTOCOL_VERSION,
! 1081: sizeof (omapi_protocol_header_t));
! 1082: if (status != ISC_R_SUCCESS)
! 1083: goto lose;
! 1084:
! 1085: omapi_protocol_dereference (&obj, MDL);
! 1086: return status;
! 1087: }
! 1088:
! 1089: isc_result_t omapi_protocol_listener_set_value (omapi_object_t *h,
! 1090: omapi_object_t *id,
! 1091: omapi_data_string_t *name,
! 1092: omapi_typed_data_t *value)
! 1093: {
! 1094: if (h -> type != omapi_type_protocol_listener)
! 1095: return ISC_R_INVALIDARG;
! 1096:
! 1097: if (h -> inner && h -> inner -> type -> set_value)
! 1098: return (*(h -> inner -> type -> set_value))
! 1099: (h -> inner, id, name, value);
! 1100: return ISC_R_NOTFOUND;
! 1101: }
! 1102:
! 1103: isc_result_t omapi_protocol_listener_get_value (omapi_object_t *h,
! 1104: omapi_object_t *id,
! 1105: omapi_data_string_t *name,
! 1106: omapi_value_t **value)
! 1107: {
! 1108: if (h -> type != omapi_type_protocol_listener)
! 1109: return ISC_R_INVALIDARG;
! 1110:
! 1111: if (h -> inner && h -> inner -> type -> get_value)
! 1112: return (*(h -> inner -> type -> get_value))
! 1113: (h -> inner, id, name, value);
! 1114: return ISC_R_NOTFOUND;
! 1115: }
! 1116:
! 1117: isc_result_t omapi_protocol_listener_destroy (omapi_object_t *h,
! 1118: const char *file, int line)
! 1119: {
! 1120: if (h -> type != omapi_type_protocol_listener)
! 1121: return ISC_R_INVALIDARG;
! 1122: return ISC_R_SUCCESS;
! 1123: }
! 1124:
! 1125: /* Write all the published values associated with the object through the
! 1126: specified connection. */
! 1127:
! 1128: isc_result_t omapi_protocol_listener_stuff (omapi_object_t *c,
! 1129: omapi_object_t *id,
! 1130: omapi_object_t *p)
! 1131: {
! 1132: if (p -> type != omapi_type_protocol_listener)
! 1133: return ISC_R_INVALIDARG;
! 1134:
! 1135: if (p -> inner && p -> inner -> type -> stuff_values)
! 1136: return (*(p -> inner -> type -> stuff_values)) (c, id,
! 1137: p -> inner);
! 1138: return ISC_R_SUCCESS;
! 1139: }
! 1140:
! 1141: isc_result_t omapi_protocol_send_status (omapi_object_t *po,
! 1142: omapi_object_t *id,
! 1143: isc_result_t waitstatus,
! 1144: unsigned rid, const char *msg)
! 1145: {
! 1146: isc_result_t status;
! 1147: omapi_message_object_t *message = (omapi_message_object_t *)0;
! 1148: omapi_object_t *mo;
! 1149:
! 1150: if (po -> type != omapi_type_protocol)
! 1151: return ISC_R_INVALIDARG;
! 1152:
! 1153: status = omapi_message_new ((omapi_object_t **)&message, MDL);
! 1154: if (status != ISC_R_SUCCESS)
! 1155: return status;
! 1156: mo = (omapi_object_t *)message;
! 1157:
! 1158: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1159: "op", OMAPI_OP_STATUS);
! 1160: if (status != ISC_R_SUCCESS) {
! 1161: omapi_message_dereference (&message, MDL);
! 1162: return status;
! 1163: }
! 1164:
! 1165: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1166: "rid", (int)rid);
! 1167: if (status != ISC_R_SUCCESS) {
! 1168: omapi_message_dereference (&message, MDL);
! 1169: return status;
! 1170: }
! 1171:
! 1172: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1173: "result", (int)waitstatus);
! 1174: if (status != ISC_R_SUCCESS) {
! 1175: omapi_message_dereference (&message, MDL);
! 1176: return status;
! 1177: }
! 1178:
! 1179: /* If a message has been provided, send it. */
! 1180: if (msg) {
! 1181: status = omapi_set_string_value (mo, (omapi_object_t *)0,
! 1182: "message", msg);
! 1183: if (status != ISC_R_SUCCESS) {
! 1184: omapi_message_dereference (&message, MDL);
! 1185: return status;
! 1186: }
! 1187: }
! 1188:
! 1189: status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
! 1190: omapi_message_dereference (&message, MDL);
! 1191: return status;
! 1192: }
! 1193:
! 1194: /* The OMAPI_NOTIFY_PROTOCOL flag will cause the notify-object for the
! 1195: message to be set to the protocol object. This is used when opening
! 1196: the default authenticator. */
! 1197:
! 1198: isc_result_t omapi_protocol_send_open (omapi_object_t *po,
! 1199: omapi_object_t *id,
! 1200: const char *type,
! 1201: omapi_object_t *object,
! 1202: unsigned flags)
! 1203: {
! 1204: isc_result_t status;
! 1205: omapi_message_object_t *message = (omapi_message_object_t *)0;
! 1206: omapi_object_t *mo;
! 1207:
! 1208: if (po -> type != omapi_type_protocol)
! 1209: return ISC_R_INVALIDARG;
! 1210:
! 1211: status = omapi_message_new ((omapi_object_t **)&message, MDL);
! 1212: mo = (omapi_object_t *)message;
! 1213:
! 1214: if (status == ISC_R_SUCCESS)
! 1215: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1216: "op", OMAPI_OP_OPEN);
! 1217:
! 1218: if (status == ISC_R_SUCCESS)
! 1219: status = omapi_set_object_value (mo, (omapi_object_t *)0,
! 1220: "object", object);
! 1221:
! 1222: if ((flags & OMAPI_CREATE) && (status == ISC_R_SUCCESS))
! 1223: status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
! 1224: "create", 1);
! 1225:
! 1226: if ((flags & OMAPI_UPDATE) && (status == ISC_R_SUCCESS))
! 1227: status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
! 1228: "update", 1);
! 1229:
! 1230: if ((flags & OMAPI_EXCL) && (status == ISC_R_SUCCESS))
! 1231: status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
! 1232: "exclusive", 1);
! 1233:
! 1234: if ((flags & OMAPI_NOTIFY_PROTOCOL) && (status == ISC_R_SUCCESS))
! 1235: status = omapi_set_object_value (mo, (omapi_object_t *)0,
! 1236: "notify-object", po);
! 1237:
! 1238: if (type && (status == ISC_R_SUCCESS))
! 1239: status = omapi_set_string_value (mo, (omapi_object_t *)0,
! 1240: "type", type);
! 1241:
! 1242: if (status == ISC_R_SUCCESS)
! 1243: status = omapi_message_register (mo);
! 1244:
! 1245: if (status == ISC_R_SUCCESS) {
! 1246: status = omapi_protocol_send_message (po, id, mo,
! 1247: (omapi_object_t *)0);
! 1248: if (status != ISC_R_SUCCESS)
! 1249: omapi_message_unregister (mo);
! 1250: }
! 1251:
! 1252: if (message)
! 1253: omapi_message_dereference (&message, MDL);
! 1254:
! 1255: return status;
! 1256: }
! 1257:
! 1258: isc_result_t omapi_protocol_send_update (omapi_object_t *po,
! 1259: omapi_object_t *id,
! 1260: unsigned rid,
! 1261: omapi_object_t *object)
! 1262: {
! 1263: isc_result_t status;
! 1264: omapi_message_object_t *message = (omapi_message_object_t *)0;
! 1265: omapi_object_t *mo;
! 1266:
! 1267: if (po -> type != omapi_type_protocol)
! 1268: return ISC_R_INVALIDARG;
! 1269:
! 1270: status = omapi_message_new ((omapi_object_t **)&message, MDL);
! 1271: if (status != ISC_R_SUCCESS)
! 1272: return status;
! 1273: mo = (omapi_object_t *)message;
! 1274:
! 1275: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1276: "op", OMAPI_OP_UPDATE);
! 1277: if (status != ISC_R_SUCCESS) {
! 1278: omapi_message_dereference (&message, MDL);
! 1279: return status;
! 1280: }
! 1281:
! 1282: if (rid) {
! 1283: omapi_handle_t handle;
! 1284: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1285: "rid", (int)rid);
! 1286: if (status != ISC_R_SUCCESS) {
! 1287: omapi_message_dereference (&message, MDL);
! 1288: return status;
! 1289: }
! 1290:
! 1291: status = omapi_object_handle (&handle, object);
! 1292: if (status != ISC_R_SUCCESS) {
! 1293: omapi_message_dereference (&message, MDL);
! 1294: return status;
! 1295: }
! 1296: status = omapi_set_int_value (mo, (omapi_object_t *)0,
! 1297: "handle", (int)handle);
! 1298: if (status != ISC_R_SUCCESS) {
! 1299: omapi_message_dereference (&message, MDL);
! 1300: return status;
! 1301: }
! 1302: }
! 1303:
! 1304: status = omapi_set_object_value (mo, (omapi_object_t *)0,
! 1305: "object", object);
! 1306: if (status != ISC_R_SUCCESS) {
! 1307: omapi_message_dereference (&message, MDL);
! 1308: return status;
! 1309: }
! 1310:
! 1311: status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
! 1312: omapi_message_dereference (&message, MDL);
! 1313: return status;
! 1314: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>