isc_result_t omapi_connect (omapi_object_t *c, const char *server_name, unsigned port) { struct hostent *he; unsigned i, hix; omapi_addr_list_t *addrs = (omapi_addr_list_t *)0; struct in_addr foo; isc_result_t status; #ifdef DEBUG_PROTOCOL log_debug ("omapi_connect(%s, port=%d)", server_name, port); #endif if (!inet_aton (server_name, &foo)) { /* If we didn't get a numeric address, try for a domain name. It's okay for this call to block. */ he = gethostbyname (server_name); if (!he) return DHCP_R_HOSTUNKNOWN; for (i = 0; he -> h_addr_list [i]; i++) ; if (i == 0) return DHCP_R_HOSTUNKNOWN; hix = i; status = omapi_addr_list_new (&addrs, hix, MDL); if (status != ISC_R_SUCCESS) return status; for (i = 0; i < hix; i++) { addrs -> addresses [i].addrtype = he -> h_addrtype; addrs -> addresses [i].addrlen = he -> h_length; memcpy (addrs -> addresses [i].address, he -> h_addr_list [i], (unsigned)he -> h_length); addrs -> addresses [i].port = port; } } else { status = omapi_addr_list_new (&addrs, 1, MDL); if (status != ISC_R_SUCCESS) return status; addrs -> addresses [0].addrtype = AF_INET; addrs -> addresses [0].addrlen = sizeof foo; memcpy (addrs -> addresses [0].address, &foo, sizeof foo); addrs -> addresses [0].port = port; hix = 1; } status = omapi_connect_list (c, addrs, (omapi_addr_t *)0); omapi_addr_list_dereference (&addrs, MDL); return status; }
/* 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_connection_destroy (omapi_object_t *h, const char *file, int line) { omapi_connection_object_t *c; //ScenSim-Port//#ifdef DEBUG_PROTOCOL //ScenSim-Port// log_debug ("omapi_connection_destroy()"); //ScenSim-Port//#endif if (h -> type != omapi_type_connection) return ISC_R_UNEXPECTED; c = (omapi_connection_object_t *)(h); if (c -> state == omapi_connection_connected) omapi_disconnect (h, 1); //ScenSim-Port// if (c -> listener) //ScenSim-Port// omapi_listener_dereference (&c -> listener, file, line); if (c -> connect_list) omapi_addr_list_dereference (&c -> connect_list, file, line); 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; }