isc_result_t dhcpctl_remote_signal_handler (omapi_object_t *o, const char *name, va_list ap) { dhcpctl_remote_object_t *p; omapi_typed_data_t *tv; if (o -> type != dhcpctl_remote_type) return DHCP_R_INVALIDARG; p = (dhcpctl_remote_object_t *)o; if (!strcmp (name, "updated")) { p -> waitstatus = ISC_R_SUCCESS; if (o -> inner -> type == omapi_type_generic) omapi_generic_clear_flags (o -> inner); return omapi_signal_in (o -> inner, "ready"); } if (!strcmp (name, "status")) { p -> waitstatus = va_arg (ap, isc_result_t); if (p -> message) omapi_typed_data_dereference (&p -> message, MDL); tv = va_arg (ap, omapi_typed_data_t *); if (tv) omapi_typed_data_reference (&p -> message, tv, MDL); return omapi_signal_in (o -> inner, "ready"); }
isc_result_t omapi_protocol_add_auth (omapi_object_t *po, omapi_object_t *ao, omapi_handle_t handle) { omapi_protocol_object_t *p; omapi_remote_auth_t *r; isc_result_t status; if (ao -> type != omapi_type_auth_key && (!ao -> inner || ao -> inner -> type != omapi_type_auth_key)) return ISC_R_INVALIDARG; if (po -> type != omapi_type_protocol) return ISC_R_INVALIDARG; p = (omapi_protocol_object_t *)po; #ifdef DEBUG_PROTOCOL log_debug ("omapi_protocol_add_auth(name=%s)", ((omapi_auth_key_t *)ao) -> name); #endif if (p -> verify_auth) { status = (p -> verify_auth) (po, (omapi_auth_key_t *)ao); if (status != ISC_R_SUCCESS) return status; } /* If omapi_protocol_connect() was called with a default authenticator, p -> default_auth will already be set, but p -> remote_auth_list will not yet be initialized. */ if (p -> default_auth && !p -> remote_auth_list) { if (p -> default_auth -> a != ao) { /* Something just went horribly wrong. */ omapi_disconnect (p -> outer, 1); return ISC_R_UNEXPECTED; } p -> remote_auth_list = p -> default_auth; p -> default_auth -> remote_handle = handle; return omapi_signal_in (p -> inner, "ready"); } r = dmalloc (sizeof(*r), MDL); if (!r) return ISC_R_NOMEMORY; status = omapi_object_reference (&r -> a, ao, MDL); if (status != ISC_R_SUCCESS) { dfree (r, MDL); return status; } r -> remote_handle = handle; r -> next = p -> remote_auth_list; p -> remote_auth_list = r; return ISC_R_SUCCESS; }
/* Find the matching connect object, if there is one. */ omapi_array_foreach_begin (omapi_connections, omapi_connection_object_t, lp) { for (i = 0; (lp -> connect_list && i < lp -> connect_list -> count); i++) { if (!memcmp (&remote.sin_addr, &lp -> connect_list -> addresses [i].address, sizeof remote.sin_addr) && (ntohs (remote.sin_port) == lp -> connect_list -> addresses [i].port)) lp -> state = omapi_connection_connected; lp -> remote_addr = remote; lp -> remote_addr.sin_family = AF_INET; omapi_addr_list_dereference (&lp -> connect_list, MDL); lp -> index = connect_index; status = omapi_signal_in ((omapi_object_t *)lp, "connect"); omapi_connection_dereference (&lp, MDL); return; } } omapi_array_foreach_end (omapi_connections,
isc_result_t omapi_one_dispatch (omapi_object_t *wo, struct timeval *t) { fd_set r, w, x, rr, ww, xx; int max = 0; int count; int desc; struct timeval now, to; omapi_io_object_t *io, *prev, *next; omapi_waiter_object_t *waiter; omapi_object_t *tmp = (omapi_object_t *)0; isc_result_t status; if (!wo || wo -> type != omapi_type_waiter) waiter = (omapi_waiter_object_t *)0; else waiter = (omapi_waiter_object_t *)wo; FD_ZERO (&x); /* First, see if the timeout has expired, and if so return. */ if (t) { gettimeofday (&now, (struct timezone *)0); cur_tv.tv_sec = now.tv_sec; cur_tv.tv_usec = now.tv_usec; if (now.tv_sec > t -> tv_sec || (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec)) return ISC_R_TIMEDOUT; /* We didn't time out, so figure out how long until we do. */ to.tv_sec = t -> tv_sec - now.tv_sec; to.tv_usec = t -> tv_usec - now.tv_usec; if (to.tv_usec < 0) { to.tv_usec += 1000000; to.tv_sec--; } /* It is possible for the timeout to get set larger than the largest time select() is willing to accept. Restricting the timeout to a maximum of one day should work around this. -DPN. (Ref: Bug #416) */ if (to.tv_sec > (60 * 60 * 24)) to.tv_sec = 60 * 60 * 24; } /* If the object we're waiting on has reached completion, return now. */ if (waiter && waiter -> ready) return ISC_R_SUCCESS; again: /* If we have no I/O state, we can't proceed. */ if (!(io = omapi_io_states.next)) return ISC_R_NOMORE; /* Set up the read and write masks. */ FD_ZERO (&r); FD_ZERO (&w); for (; io; io = io -> next) { /* Check for a read socket. If we shouldn't be trying to read for this I/O object, either there won't be a readfd function, or it'll return -1. */ if (io -> readfd && io -> inner && (desc = (*(io -> readfd)) (io -> inner)) >= 0) { FD_SET (desc, &r); if (desc > max) max = desc; } /* Same deal for write fdets. */ if (io -> writefd && io -> inner && (desc = (*(io -> writefd)) (io -> inner)) >= 0) { FD_SET (desc, &w); if (desc > max) max = desc; } } /* poll if all reader are dry */ now.tv_sec = 0; now.tv_usec = 0; rr=r; ww=w; xx=x; /* poll once */ count = select(max + 1, &r, &w, &x, &now); if (!count) { /* We are dry now */ trigger_event(&rw_queue_empty); /* Wait for a packet or a timeout... XXX */ r = rr; w = ww; x = xx; count = select(max + 1, &r, &w, &x, t ? &to : NULL); } /* Get the current time... */ gettimeofday (&cur_tv, (struct timezone *)0); /* We probably have a bad file descriptor. Figure out which one. When we find it, call the reaper function on it, which will maybe make it go away, and then try again. */ if (count < 0) { struct timeval t0; omapi_io_object_t *prev = (omapi_io_object_t *)0; io = (omapi_io_object_t *)0; if (omapi_io_states.next) omapi_io_reference (&io, omapi_io_states.next, MDL); while (io) { omapi_object_t *obj; FD_ZERO (&r); FD_ZERO (&w); t0.tv_sec = t0.tv_usec = 0; if (io -> readfd && io -> inner && (desc = (*(io -> readfd)) (io -> inner)) >= 0) { FD_SET (desc, &r); count = select (desc + 1, &r, &w, &x, &t0); bogon: if (count < 0) { log_error ("Bad descriptor %d.", desc); for (obj = (omapi_object_t *)io; obj -> outer; obj = obj -> outer) ; for (; obj; obj = obj -> inner) { omapi_value_t *ov; int len; const char *s; ov = (omapi_value_t *)0; status = omapi_get_value_str (obj, (omapi_object_t *)0, "name", &ov); if(status!=ISC_R_SUCCESS){ log_error("omapi_get_value_str failed!\n"); } if (ov && ov -> value && (ov -> value -> type == omapi_datatype_string)) { s = (char *) ov -> value -> u.buffer.value; len = ov -> value -> u.buffer.len; } else { s = ""; len = 0; } log_error ("Object %lx %s%s%.*s", (unsigned long)obj, obj -> type -> name, len ? " " : "", len, s); if (len) omapi_value_dereference (&ov, MDL); } (*(io -> reaper)) (io -> inner); if (prev) { omapi_io_dereference (&prev -> next, MDL); if (io -> next) omapi_io_reference (&prev -> next, io -> next, MDL); } else { omapi_io_dereference (&omapi_io_states.next, MDL); if (io -> next) omapi_io_reference (&omapi_io_states.next, io -> next, MDL); } omapi_io_dereference (&io, MDL); goto again; } } FD_ZERO (&r); FD_ZERO (&w); t0.tv_sec = t0.tv_usec = 0; /* Same deal for write fdets. */ if (io -> writefd && io -> inner && (desc = (*(io -> writefd)) (io -> inner)) >= 0) { FD_SET (desc, &w); count = select (desc + 1, &r, &w, &x, &t0); if (count < 0) goto bogon; } if (prev) omapi_io_dereference (&prev, MDL); omapi_io_reference (&prev, io, MDL); omapi_io_dereference (&io, MDL); if (prev -> next) omapi_io_reference (&io, prev -> next, MDL); } if (prev) omapi_io_dereference (&prev, MDL); } for (io = omapi_io_states.next; io; io = io -> next) { if (!io -> inner) continue; omapi_object_reference (&tmp, io -> inner, MDL); /* Check for a read descriptor, and if there is one, see if we got input on that socket. */ if (io -> readfd && (desc = (*(io -> readfd)) (tmp)) >= 0) { if (FD_ISSET (desc, &r)) ((*(io -> reader)) (tmp)); } /* Same deal for write descriptors. */ if (io -> writefd && (desc = (*(io -> writefd)) (tmp)) >= 0) { if (FD_ISSET (desc, &w)) ((*(io -> writer)) (tmp)); } omapi_object_dereference (&tmp, MDL); } /* Now check for I/O handles that are no longer valid, and remove them from the list. */ prev = NULL; io = NULL; if (omapi_io_states.next != NULL) { omapi_io_reference(&io, omapi_io_states.next, MDL); } while (io != NULL) { if ((io->inner == NULL) || ((io->reaper != NULL) && ((io->reaper)(io->inner) != ISC_R_SUCCESS))) { omapi_io_object_t *tmp = NULL; /* Save a reference to the next pointer, if there is one. */ if (io->next != NULL) { omapi_io_reference(&tmp, io->next, MDL); omapi_io_dereference(&io->next, MDL); } if (prev != NULL) { omapi_io_dereference(&prev->next, MDL); if (tmp != NULL) omapi_io_reference(&prev->next, tmp, MDL); } else { omapi_io_dereference(&omapi_io_states.next, MDL); if (tmp != NULL) omapi_io_reference (&omapi_io_states.next, tmp, MDL); else omapi_signal_in( (omapi_object_t *) &omapi_io_states, "ready"); } if (tmp != NULL) omapi_io_dereference(&tmp, MDL); } else { if (prev != NULL) { omapi_io_dereference(&prev, MDL); } omapi_io_reference(&prev, io, MDL); } /* * Equivalent to: * io = io->next * But using our reference counting voodoo. */ next = NULL; if (io->next != NULL) { omapi_io_reference(&next, io->next, MDL); } omapi_io_dereference(&io, MDL); if (next != NULL) { omapi_io_reference(&io, next, MDL); omapi_io_dereference(&next, MDL); } } if (prev != NULL) { omapi_io_dereference(&prev, MDL); } return ISC_R_SUCCESS; }
isc_result_t omapi_protocol_signal_handler (omapi_object_t *h, const char *name, va_list ap) { isc_result_t status; omapi_protocol_object_t *p; omapi_object_t *c; omapi_message_object_t *m; omapi_value_t *signature; u_int16_t nlen; u_int32_t vlen; u_int32_t th; #if defined (DEBUG_MEMORY_LEAKAGE) unsigned long previous_outstanding = 0xDEADBEEF; unsigned long connect_outstanding = 0xDEADBEEF; #endif if (h -> type != omapi_type_protocol) { /* XXX shouldn't happen. Put an assert here? */ return ISC_R_UNEXPECTED; } p = (omapi_protocol_object_t *)h; if (!strcmp (name, "connect")) { #if defined (DEBUG_MEMORY_LEAKAGE) connect_outstanding = dmalloc_outstanding; #endif /* Send the introductory message. */ status = omapi_protocol_send_intro (h, OMAPI_PROTOCOL_VERSION, sizeof (omapi_protocol_header_t)); if (status != ISC_R_SUCCESS) { omapi_disconnect (p -> outer, 1); return status; } return ISC_R_SUCCESS; } /* Should only receive these when opening the initial authenticator. */ if (!strcmp (name, "status")) { status = va_arg (ap, isc_result_t); if (status != ISC_R_SUCCESS) { omapi_signal_in (h -> inner, "status", status, (omapi_object_t *)0); omapi_disconnect (p -> outer, 1); return status; } else { return omapi_signal_in (h -> inner, "ready"); } } /* If we get a disconnect, dump memory usage. */ if (!strcmp (name, "disconnect")) { #if defined (DEBUG_MEMORY_LEAKAGE) if (connect_outstanding != 0xDEADBEEF) { log_info ("generation %ld: %ld new, %ld outstanding, %ld%s", dmalloc_generation, dmalloc_outstanding - previous_outstanding, dmalloc_outstanding, dmalloc_longterm, " long-term"); } #endif #if defined (DEBUG_MEMORY_LEAKAGE) dmalloc_dump_outstanding (); #endif #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) dump_rc_history (); #endif for (m = omapi_registered_messages; m; m = m -> next) { if (m -> protocol_object == p) { if (m -> object) omapi_signal (m -> object, "disconnect"); } } } /* Not a signal we recognize? */ if (strcmp (name, "ready")) { if (p -> inner && p -> inner -> type -> signal_handler) return (*(p -> inner -> type -> signal_handler)) (h, name, ap); return ISC_R_NOTFOUND; } if (!p -> outer || p -> outer -> type != omapi_type_connection) return ISC_R_INVALIDARG; c = p -> outer; /* We get here because we requested that we be woken up after some number of bytes were read, and that number of bytes has in fact been read. */ switch (p -> state) { case omapi_protocol_intro_wait: /* Get protocol version and header size in network byte order. */ omapi_connection_get_uint32 (c, &p -> protocol_version); omapi_connection_get_uint32 (c, &p -> header_size); /* We currently only support the current protocol version. */ if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) { omapi_disconnect (c, 1); return ISC_R_VERSIONMISMATCH; } if (p -> header_size < sizeof (omapi_protocol_header_t)) { omapi_disconnect (c, 1); return ISC_R_PROTOCOLERROR; } if (p -> default_auth) { status = omapi_protocol_send_open (h, (omapi_object_t *)0, "authenticator", p -> default_auth -> a, OMAPI_NOTIFY_PROTOCOL); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; } } else { status = omapi_signal_in (h -> inner, "ready"); } to_header_wait: /* The next thing we're expecting is a message header. */ p -> state = omapi_protocol_header_wait; /* Register a need for the number of bytes in a header, and if we already have that many, process them immediately. */ if ((omapi_connection_require (c, p -> header_size)) != ISC_R_SUCCESS) break; /* If we already have the data, fall through. */ case omapi_protocol_header_wait: #if defined (DEBUG_MEMORY_LEAKAGE) if (previous_outstanding != 0xDEADBEEF) { log_info ("%s %ld: %ld new, %ld outstanding, %ld%s", "generation", dmalloc_generation, dmalloc_outstanding - previous_outstanding, dmalloc_outstanding, dmalloc_longterm, " long-term"); #endif #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) dmalloc_dump_outstanding (); #endif #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) dump_rc_history (); #endif #if defined (DEBUG_MEMORY_LEAKAGE) } previous_outstanding = dmalloc_outstanding; #endif status = omapi_message_new ((omapi_object_t **)&p -> message, MDL); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; } p -> verify_result = ISC_R_SUCCESS; /* Swap in the header... */ omapi_connection_get_uint32 (c, &p -> message -> authid); /* Bind the authenticator to the message object. */ if (p -> message -> authid) { status = (omapi_protocol_lookup_auth (&p -> message -> id_object, h, p -> message -> authid)); if (status != ISC_R_SUCCESS) p -> verify_result = status; /* Activate the authentication key. */ status = omapi_set_object_value (c, (omapi_object_t *)0, "input-authenticator", p -> message -> id_object); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; } } omapi_connection_get_uint32 (c, &p -> message -> authlen); omapi_connection_get_uint32 (c, &p -> message -> op); omapi_connection_get_uint32 (c, &th); p -> message -> h = th; omapi_connection_get_uint32 (c, &p -> message -> id); omapi_connection_get_uint32 (c, &p -> message -> rid); /* If there was any extra header data, skip over it. */ if (p -> header_size > sizeof (omapi_protocol_header_t)) { omapi_connection_copyout (0, c, (p -> header_size - sizeof (omapi_protocol_header_t))); } /* XXX must compute partial signature across the XXX preceding bytes. Also, if authenticator specifies encryption as well as signing, we may have to decrypt the data on the way in. */ /* First we read in message-specific values, then object values. */ p -> reading_message_values = 1; need_name_length: /* The next thing we're expecting is length of the first name. */ p -> state = omapi_protocol_name_length_wait; /* Wait for a 16-bit length. */ if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS) break; /* If it's already here, fall through. */ case omapi_protocol_name_length_wait: omapi_connection_get_uint16 (c, &nlen); /* A zero-length name means that we're done reading name+value pairs. */ if (nlen == 0) { /* If we've already read in the object, we are done reading the message, but if we've just finished reading in the values associated with the message, we need to read the object. */ if (p -> reading_message_values) { p -> reading_message_values = 0; goto need_name_length; } /* If the authenticator length is zero, there's no signature to read in, so go straight to processing the message. */ if (p -> message -> authlen == 0) goto message_done; /* The next thing we're expecting is the message signature. */ p -> state = omapi_protocol_signature_wait; /* Wait for the number of bytes specified for the authenticator. If we already have it, go read it in. */ if (omapi_connection_require (c, p -> message -> authlen) == ISC_R_SUCCESS) goto signature_wait; break; } /* Allocate a buffer for the name. */ status = (omapi_data_string_new (&p -> name, nlen, MDL)); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return ISC_R_NOMEMORY; } p -> state = omapi_protocol_name_wait; if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS) break; /* If it's already here, fall through. */ case omapi_protocol_name_wait: omapi_connection_copyout (p -> name -> value, c, p -> name -> len); /* Wait for a 32-bit length. */ p -> state = omapi_protocol_value_length_wait; if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS) break; /* If it's already here, fall through. */ case omapi_protocol_value_length_wait: omapi_connection_get_uint32 (c, &vlen); /* Zero-length values are allowed - if we get one, we don't have to read any data for the value - just get the next one, if there is a next one. */ if (!vlen) goto insert_new_value; status = omapi_typed_data_new (MDL, &p -> value, omapi_datatype_data, vlen); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return ISC_R_NOMEMORY; } p -> state = omapi_protocol_value_wait; if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS) break; /* If it's already here, fall through. */ case omapi_protocol_value_wait: omapi_connection_copyout (p -> value -> u.buffer.value, c, p -> value -> u.buffer.len); insert_new_value: if (p -> reading_message_values) { status = (omapi_set_value ((omapi_object_t *)p -> message, p -> message -> id_object, p -> name, p -> value)); } else { if (!p -> message -> object) { /* We need a generic object to hang off of the incoming message. */ status = (omapi_generic_new (&p -> message -> object, MDL)); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; } } status = (omapi_set_value ((omapi_object_t *)p -> message -> object, p -> message -> id_object, p -> name, p -> value)); } if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; } omapi_data_string_dereference (&p -> name, MDL); if (p -> value) omapi_typed_data_dereference (&p -> value, MDL); goto need_name_length; signature_wait: case omapi_protocol_signature_wait: if (p -> message -> id_object) { /* Compute the signature of the message. */ signature = (omapi_value_t *)0; status = omapi_get_value_str (c, (omapi_object_t *)0, "input-signature", &signature); if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return status; } /* Disable the authentication key on the connection. */ status = omapi_set_value_str (c, (omapi_object_t *)0, "input-authenticator", (omapi_typed_data_t *)0); if (status != ISC_R_SUCCESS) { omapi_value_dereference (&signature, MDL); omapi_disconnect (c, 1); return status; } } /* Read the authenticator. */ status = omapi_typed_data_new (MDL, &p -> message -> authenticator, omapi_datatype_data, p -> message -> authlen); if (status != ISC_R_SUCCESS) { omapi_value_dereference (&signature, MDL); omapi_disconnect (c, 1); return ISC_R_NOMEMORY; } omapi_connection_copyout (p -> message -> authenticator -> u.buffer.value, c, p -> message -> authlen); /* Verify the signature. */ if (p -> message -> id_object && ((signature -> value -> u.buffer.len != p -> message -> authlen) || (memcmp (signature -> value -> u.buffer.value, p -> message -> authenticator -> u.buffer.value, p -> message -> authlen) != 0))) { /* Invalid signature. */ p -> verify_result = ISC_R_INVALIDKEY; } omapi_value_dereference (&signature, MDL); /* Process the message. */ message_done: if (p -> verify_result != ISC_R_SUCCESS) { status = omapi_protocol_send_status (h, (omapi_object_t *)0, p -> verify_result, p -> message -> id, (char *)0); } else { status = omapi_message_process ((omapi_object_t *)p -> message, h); } if (status != ISC_R_SUCCESS) { omapi_disconnect (c, 1); return ISC_R_NOMEMORY; } omapi_message_dereference (&p -> message, MDL); #if defined (DEBUG_MEMORY_LEAKAGE) log_info ("generation %ld: %ld new, %ld outstanding, %ld%s", dmalloc_generation, dmalloc_outstanding - previous_outstanding, dmalloc_outstanding, dmalloc_longterm, " long-term"); #endif #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL)) dmalloc_dump_outstanding (); #endif #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY) dump_rc_history (); #endif #if defined (DEBUG_MEMORY_LEAKAGE) previous_outstanding = 0xDEADBEEF; #endif /* Now wait for the next message. */ goto to_header_wait; default: /* XXX should never get here. Assertion? */ break; } return ISC_R_SUCCESS; }
static isc_result_t omapi_connection_connect_internal (omapi_object_t *h) { int error; omapi_connection_object_t *c; socklen_t sl; isc_result_t status; if (h -> type != omapi_type_connection) return DHCP_R_INVALIDARG; c = (omapi_connection_object_t *)h; if (c -> state == omapi_connection_connecting) { sl = sizeof error; //ScenSim-Port// if (getsockopt (c -> socket, SOL_SOCKET, SO_ERROR, //ScenSim-Port// (char *)&error, &sl) < 0) { //ScenSim-Port// omapi_disconnect (h, 1); //ScenSim-Port// return ISC_R_SUCCESS; //ScenSim-Port// } if (!error) c -> state = omapi_connection_connected; } if (c -> state == omapi_connection_connecting || c -> state == omapi_connection_unconnected) { if (c -> cptr >= c -> connect_list -> count) { switch (error) { case ECONNREFUSED: status = ISC_R_CONNREFUSED; break; case ENETUNREACH: status = ISC_R_NETUNREACH; break; default: status = uerr2isc (error); break; } omapi_disconnect (h, 1); return status; } if (c -> connect_list -> addresses [c -> cptr].addrtype != AF_INET) { omapi_disconnect (h, 1); return DHCP_R_INVALIDARG; } memcpy (&c -> remote_addr.sin_addr, &c -> connect_list -> addresses [c -> cptr].address, sizeof c -> remote_addr.sin_addr); c -> remote_addr.sin_family = AF_INET; c -> remote_addr.sin_port = htons (c -> connect_list -> addresses [c -> cptr].port); //ScenSim-Port//#if defined (HAVE_SA_LEN) //ScenSim-Port// c -> remote_addr.sin_len = sizeof c -> remote_addr; //ScenSim-Port//#endif memset (&c -> remote_addr.sin_zero, 0, sizeof c -> remote_addr.sin_zero); ++c -> cptr; //ScenSim-Port// error = connect (c -> socket, //ScenSim-Port// (struct sockaddr *)&c -> remote_addr, //ScenSim-Port// sizeof c -> remote_addr); if (error < 0) { error = errno; if (error != EINPROGRESS) { omapi_disconnect (h, 1); switch (error) { case ECONNREFUSED: status = ISC_R_CONNREFUSED; break; case ENETUNREACH: status = ISC_R_NETUNREACH; break; default: status = uerr2isc (error); break; } return status; } c -> state = omapi_connection_connecting; return DHCP_R_INCOMPLETE; } c -> state = omapi_connection_connected; } /* I don't know why this would fail, so I'm tempted not to test the return value. */ sl = sizeof (c -> local_addr); //ScenSim-Port// if (getsockname (c -> socket, //ScenSim-Port// (struct sockaddr *)&c -> local_addr, &sl) < 0) { //ScenSim-Port// } /* Reregister with the I/O object. If we don't already have an I/O object this turns into a register call, otherwise we simply modify the pointers in the I/O object. */ status = omapi_reregister_io_object (h, omapi_connection_readfd, omapi_connection_writefd, omapi_connection_reader, omapi_connection_writer, omapi_connection_reaper); if (status != ISC_R_SUCCESS) { omapi_disconnect (h, 1); return status; } omapi_signal_in (h, "connect"); omapi_addr_list_dereference (&c -> connect_list, MDL); return ISC_R_INPROGRESS; }