Beispiel #1
0
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;
}
Beispiel #2
0
	/* 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,
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}