33 #include <arpa/inet.h>
38 static void trace_connect_input (
trace_type_t *,
unsigned,
char *);
40 static void trace_disconnect_input (
trace_type_t *,
unsigned,
char *);
46 static isc_result_t omapi_connection_connect_internal (
omapi_object_t *);
52 const
char *server_name,
62 log_debug (
"omapi_connect(%s, port=%d)", server_name, port);
65 if (!inet_aton (server_name, &foo)) {
68 he = gethostbyname (server_name);
71 for (i = 0; he -> h_addr_list [i]; i++)
80 for (i = 0; i < hix; i++) {
81 addrs -> addresses [i].addrtype = he -> h_addrtype;
82 addrs -> addresses [i].addrlen = he -> h_length;
83 memcpy (addrs -> addresses [i].address,
84 he -> h_addr_list [i],
85 (
unsigned)he -> h_length);
86 addrs -> addresses [i].port = port;
92 addrs -> addresses [0].addrtype = AF_INET;
93 addrs -> addresses [0].addrlen =
sizeof foo;
94 memcpy (addrs -> addresses [0].address, &foo,
sizeof foo);
95 addrs -> addresses [0].port = port;
109 struct sockaddr_in local_sin;
112 status = omapi_connection_allocate (&obj,
MDL);
119 omapi_connection_dereference (&obj,
MDL);
124 omapi_connection_dereference (&obj,
MDL);
133 #if defined (TRACING)
140 socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
141 if (obj -> socket < 0) {
142 omapi_connection_dereference (&obj,
MDL);
143 if (errno == EMFILE || errno == ENFILE
145 return ISC_R_NORESOURCES;
146 return ISC_R_UNEXPECTED;
152 if (local_addr -> addrtype != AF_INET) {
154 omapi_connection_dereference (&obj,
MDL);
157 local_sin.sin_port = htons (local_addr -> port);
158 memcpy (&local_sin.sin_addr,
159 local_addr -> address,
160 local_addr -> addrlen);
161 #if defined (HAVE_SA_LEN)
162 local_sin.sin_len =
sizeof local_addr;
164 local_sin.sin_family = AF_INET;
165 memset (&local_sin.sin_zero, 0,
166 sizeof local_sin.sin_zero);
168 if (bind (obj -> socket, (
struct sockaddr *)&local_sin,
169 sizeof local_sin) < 0) {
174 if (errno == EADDRINUSE)
175 return ISC_R_ADDRINUSE;
176 if (errno == EADDRNOTAVAIL)
177 return ISC_R_ADDRNOTAVAIL;
180 return ISC_R_UNEXPECTED;
182 obj -> local_addr = local_sin;
186 if (fcntl (obj -> socket, F_SETFD, 1) < 0) {
187 close (obj -> socket);
188 omapi_connection_dereference (&obj,
MDL);
189 return ISC_R_UNEXPECTED;
195 if (setsockopt (obj -> socket, SOL_SOCKET, SO_REUSEADDR,
196 (
char *)&flag,
sizeof flag) < 0) {
197 omapi_connection_dereference (&obj,
MDL);
198 return ISC_R_UNEXPECTED;
202 if (fcntl (obj -> socket, F_SETFL, O_NONBLOCK) < 0) {
203 omapi_connection_dereference (&obj,
MDL);
204 return ISC_R_UNEXPECTED;
213 if (setsockopt(obj->socket, SOL_SOCKET, SO_NOSIGPIPE,
214 (
char *)&flag,
sizeof(flag)) < 0) {
215 omapi_connection_dereference (&obj,
MDL);
216 return ISC_R_UNEXPECTED;
236 if (status == ISC_R_INPROGRESS) {
239 #if defined (TRACING)
245 omapi_connection_dereference (&obj,
MDL);
249 #if defined (TRACING)
257 trace_connect_stop,
MDL);
259 trace_disconnect_input,
260 trace_disconnect_stop,
MDL);
269 int32_t connect_index, listener_index;
270 static int32_t index;
272 if (!omapi_connections) {
273 status = omapi_connection_array_allocate (&omapi_connections,
279 status = omapi_connection_array_extend (omapi_connections, obj,
280 (
int *)0, file, line);
286 #if defined (TRACING)
297 connect_index = htonl (index);
300 listener_index = htonl (obj -> listener -> index);
302 listener_index = htonl (-1);
303 iov [iov_count].
buf = (
char *)&connect_index;
304 iov [iov_count++].
len =
sizeof connect_index;
305 iov [iov_count].
buf = (
char *)&listener_index;
306 iov [iov_count++].
len =
sizeof listener_index;
307 iov [iov_count].
buf = (
char *)&obj -> remote_addr.sin_port;
308 iov [iov_count++].
len =
sizeof obj -> remote_addr.sin_port;
309 iov [iov_count].
buf = (
char *)&obj -> local_addr.sin_port;
310 iov [iov_count++].
len =
sizeof obj -> local_addr.sin_port;
311 iov [iov_count].
buf = (
char *)&obj -> remote_addr.sin_addr;
312 iov [iov_count++].
len =
sizeof obj -> remote_addr.sin_addr;
313 iov [iov_count].
buf = (
char *)&obj -> local_addr.sin_addr;
314 iov [iov_count++].
len =
sizeof obj -> local_addr.sin_addr;
317 iov_count, iov, file, line);
323 unsigned length,
char *buf)
325 struct sockaddr_in remote, local;
326 int32_t connect_index, listener_index;
332 if (length != ((
sizeof connect_index) +
333 (
sizeof remote.sin_port) +
334 (
sizeof remote.sin_addr)) * 2) {
335 log_error (
"Trace connect: invalid length %d", length);
339 memset (&remote, 0,
sizeof remote);
340 memset (&local, 0,
sizeof local);
341 memcpy (&connect_index, s,
sizeof connect_index);
342 s +=
sizeof connect_index;
343 memcpy (&listener_index, s,
sizeof listener_index);
344 s +=
sizeof listener_index;
345 memcpy (&remote.sin_port, s,
sizeof remote.sin_port);
346 s +=
sizeof remote.sin_port;
347 memcpy (&local.sin_port, s,
sizeof local.sin_port);
348 s +=
sizeof local.sin_port;
349 memcpy (&remote.sin_addr, s,
sizeof remote.sin_addr);
350 s +=
sizeof remote.sin_addr;
351 memcpy (&local.sin_addr, s,
sizeof local.sin_addr);
352 s +=
sizeof local.sin_addr;
355 connect_index = ntohl (connect_index);
356 listener_index = ntohl (listener_index);
360 if (listener_index != -1) {
365 if (lp -> address.sin_port == local.sin_port) {
366 omapi_listener_reference (&listener, lp,
MDL);
367 omapi_listener_dereference (&lp,
MDL);
374 "Spurious traced listener connect - index ",
375 (
long int)listener_index,
376 inet_ntoa (local.sin_addr),
377 ntohs (local.sin_port));
383 log_error (
"traced listener connect: %s",
384 isc_result_totext (status));
387 omapi_connection_dereference (&obj,
MDL);
388 omapi_listener_dereference (&listener,
MDL);
395 for (i = 0; (lp->connect_list &&
396 i < lp->connect_list->count); i++) {
397 if (!memcmp (&remote.sin_addr,
398 &lp->connect_list->addresses[i].address,
399 sizeof remote.sin_addr) &&
400 (ntohs (remote.sin_port) ==
401 lp->connect_list->addresses[i].port)) {
403 lp->remote_addr = remote;
404 lp->remote_addr.sin_family = AF_INET;
406 lp->index = connect_index;
409 omapi_connection_dereference (&lp,
MDL);
416 log_error (
"Spurious traced connect - index %ld, addr %s, port %d",
417 (
long int)connect_index, inet_ntoa (remote.sin_addr),
418 ntohs (remote.sin_port));
422 static void trace_connect_stop (
trace_type_t *ttype) { }
424 static void trace_disconnect_input (
trace_type_t *ttype,
425 unsigned length,
char *buf)
428 if (length !=
sizeof *index) {
429 log_error (
"trace disconnect: wrong length %d", length);
433 index = (int32_t *)buf;
437 if (lp -> index == ntohl (*index)) {
439 omapi_connection_dereference (&lp,
MDL);
445 log_error (
"trace disconnect: no connection matching index %ld",
446 (
long int)ntohl (*index));
449 static void trace_disconnect_stop (
trace_type_t *ttype) { }
461 #ifdef DEBUG_PROTOCOL
462 log_debug (
"omapi_disconnect(%s)", force ?
"force" :
"");
469 #if defined (TRACING)
474 index = htonl (c -> index);
476 sizeof index, (
char *)&index,
481 isc_result_totext (status));
497 if (!shutdown (c -> socket,
SHUT_RD)) {
498 if (c -> out_bytes > 0) {
506 #if defined (TRACING)
523 if (h -> outer -> inner)
538 if (h->inner != NULL) {
539 if (h->inner->outer != NULL) {
569 c -> bytes_needed = bytes;
570 if (c -> bytes_needed <= c -> in_bytes) {
616 status = omapi_connection_connect_internal (h);
617 if (status == ISC_R_INPROGRESS)
618 return ISC_R_INPROGRESS;
626 static isc_result_t omapi_connection_connect_internal (
omapi_object_t *h)
639 if (getsockopt (c -> socket, SOL_SOCKET, SO_ERROR,
640 (
char *)&error, &sl) < 0) {
649 if (c -> cptr >= c -> connect_list -> count) {
652 status = ISC_R_CONNREFUSED;
655 status = ISC_R_NETUNREACH;
665 if (c -> connect_list -> addresses [c -> cptr].addrtype !=
671 memcpy (&c -> remote_addr.sin_addr,
672 &c -> connect_list -> addresses [c -> cptr].address,
673 sizeof c -> remote_addr.sin_addr);
674 c -> remote_addr.sin_family = AF_INET;
675 c -> remote_addr.sin_port =
676 htons (c -> connect_list -> addresses [c -> cptr].port);
677 #if defined (HAVE_SA_LEN)
678 c -> remote_addr.sin_len =
sizeof c -> remote_addr;
680 memset (&c -> remote_addr.sin_zero, 0,
681 sizeof c -> remote_addr.sin_zero);
684 error = connect (c -> socket,
685 (
struct sockaddr *)&c -> remote_addr,
686 sizeof c -> remote_addr);
689 if (error != EINPROGRESS) {
693 status = ISC_R_CONNREFUSED;
696 status = ISC_R_NETUNREACH;
712 sl =
sizeof (c -> local_addr);
713 if (getsockname (c -> socket,
714 (
struct sockaddr *)&c -> local_addr, &sl) < 0) {
735 return ISC_R_INPROGRESS;
751 c -> out_bytes == 0) {
752 #ifdef DEBUG_PROTOCOL
753 log_debug (
"omapi_connection_reaper(): disconnect");
758 #ifdef DEBUG_PROTOCOL
759 log_debug (
"omapi_connection_reaper(): closed");
761 return ISC_R_NOTCONNECTED;
770 char *name_str = NULL;
796 name_str =
dmalloc (name -> value -> u.buffer.len + 1,
MDL);
798 status = ISC_R_NOMEMORY;
803 name -> value -> u.buffer.
value,
804 name -> value -> u.buffer.len);
805 name_str [name -> value -> u.buffer.len] = 0;
813 if (*dst_key == NULL)
814 status = ISC_R_NOMEMORY;
832 const unsigned char *data,
838 dst_context_t **dctx = (dst_context_t **)context;
851 region.base = (
unsigned char *)data;
853 dst_context_adddata(*dctx, ®ion);
858 unsigned int sigsize;
861 status = dst_key_sigsize(key, &sigsize);
874 status = dst_context_sign(*dctx, &sigbuf);
890 dst_context_destroy(dctx);
909 return(dst_key_sigsize(c->
out_key, l));
928 if (c -> in_context) {
941 status = make_dst_key (&c -> in_key,
953 if (c -> out_context) {
966 status = make_dst_key (&c -> out_key,
975 if (h -> inner && h -> inner -> type -> set_value)
976 return (*(h -> inner -> type -> set_value))
977 (h -> inner, id, name, value);
989 unsigned int sigsize;
996 if (!c -> in_key || !c -> in_context)
1014 status = dst_key_sigsize(c->
in_key, &sigsize);
1022 if (!c -> out_key || !c -> out_context)
1041 status = dst_key_sigsize(c->
out_key, &sigsize);
1049 if (h -> inner && h -> inner -> type -> get_value)
1050 return (*(h -> inner -> type -> get_value))
1051 (h -> inner, id, name, value);
1056 const char *file,
int line)
1060 #ifdef DEBUG_PROTOCOL
1061 log_debug (
"omapi_connection_destroy()");
1065 return ISC_R_UNEXPECTED;
1070 omapi_listener_dereference (&c -> listener, file, line);
1071 if (c -> connect_list)
1077 const char *name, va_list ap)
1082 #ifdef DEBUG_PROTOCOL
1083 log_debug (
"omapi_connection_signal_handler(%s)", name);
1086 if (h -> inner && h -> inner -> type -> signal_handler)
1087 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
1102 if (m -> inner && m -> inner -> type -> stuff_values)
1103 return (*(m -> inner -> type -> stuff_values)) (c, id,
isc_result_t omapi_reregister_io_object(omapi_object_t *, int(*)(omapi_object_t *), int(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *))
isc_result_t omapi_typed_data_new(const char *, int, omapi_typed_data_t **, omapi_datatype_t,...)
isc_result_t omapi_connection_reader(omapi_object_t *)
omapi_object_type_t * omapi_type_connection
isc_result_t omapi_register_io_object(omapi_object_t *, int(*)(omapi_object_t *), int(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *))
isc_result_t omapi_make_int_value(omapi_value_t **, omapi_data_string_t *, int, const char *, int)
isc_result_t omapi_buffer_dereference(omapi_buffer_t **, const char *, int)
isc_result_t omapi_object_reference(omapi_object_t **, omapi_object_t *, const char *, int)
#define NS_TSIG_ALG_HMAC_MD5
isc_result_t omapi_connection_destroy(omapi_object_t *, const char *, int)
dhcp_context_t dhcp_gbl_ctx
omapi_typed_data_t * value
int int int log_debug(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_signal_in(omapi_object_t *, const char *,...)
int log_error(const char *,...) __attribute__((__format__(__printf__
isc_result_t omapi_connection_reaper(omapi_object_t *)
#define OMAPI_OBJECT_ALLOC(name, stype, type)
#define DHCP_R_HOSTUNKNOWN
void omapi_connection_trace_setup(void)
int omapi_connection_writefd(omapi_object_t *)
isc_result_t omapi_connection_output_auth_length(omapi_object_t *, unsigned *)
struct omapi_typed_data_t::@3::@4 buffer
isc_result_t omapi_get_value_str(omapi_object_t *, omapi_object_t *, const char *, omapi_value_t **)
isc_result_t omapi_connection_require(omapi_object_t *, unsigned)
isc_result_t omapi_connection_set_value(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_typed_data_t *)
isc_result_t omapi_addr_list_reference(omapi_addr_list_t **, omapi_addr_list_t *, const char *, int)
trace_type_t * trace_type_register(const char *, void *, void(*)(trace_type_t *, unsigned, char *), void(*)(trace_type_t *), const char *, int)
isc_result_t omapi_connection_writer(omapi_object_t *)
isc_result_t omapi_connection_signal_handler(omapi_object_t *, const char *, va_list)
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
isc_result_t omapi_connection_stuff_values(omapi_object_t *, omapi_object_t *, omapi_object_t *)
isc_result_t omapi_signal(omapi_object_t *, const char *,...)
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
isc_result_t omapi_make_value(omapi_value_t **, omapi_data_string_t *, omapi_typed_data_t *, const char *, int)
union omapi_typed_data_t::@3 u
void omapi_connection_register(omapi_connection_object_t *, const char *, int)
isc_result_t omapi_addr_list_dereference(omapi_addr_list_t **, const char *, int)
isc_result_t uerr2isc(int)
void * dmalloc(size_t, const char *, int)
isc_result_t omapi_connection_connect(omapi_object_t *)
isc_result_t omapi_connect(omapi_object_t *, const char *, unsigned)
isc_result_t omapi_typed_data_reference(omapi_typed_data_t **, omapi_typed_data_t *, const char *, int)
isc_result_t omapi_value_dereference(omapi_value_t **, const char *, int)
isc_result_t isclib_make_dst_key(char *inname, char *algorithm, unsigned char *secret, int length, dst_key_t **dstkey)
#define DHCP_HMAC_MD5_NAME
int omapi_ds_strcmp(omapi_data_string_t *, const char *)
isc_result_t omapi_unregister_io_object(omapi_object_t *)
#define omapi_array_foreach_end(array, stype, var)
omapi_type_protocol_listener omapi_type_listener omapi_type_waiter omapi_type_message isc_result_t omapi_connection_sign_data(int mode, dst_key_t *key, void **context, const unsigned char *data, const unsigned len, omapi_typed_data_t **result)
isc_result_t omapi_listener_connect(omapi_connection_object_t **obj, omapi_listener_object_t *listener, int socket, struct sockaddr_in *remote_addr)
isc_result_t omapi_connect_list(omapi_object_t *, omapi_addr_list_t *, omapi_addr_t *)
#define OMAPI_ARRAY_TYPE(name, stype)
#define DHCP_R_INCOMPLETE
isc_result_t trace_write_packet(trace_type_t *, unsigned, const char *, const char *, int)
isc_result_t omapi_disconnect(omapi_object_t *, int)
isc_result_t omapi_connection_get_value(omapi_object_t *, omapi_object_t *, omapi_data_string_t *, omapi_value_t **)
isc_result_t omapi_typed_data_dereference(omapi_typed_data_t **, const char *, int)
#define omapi_array_foreach_begin(array, stype, var)
isc_result_t omapi_addr_list_new(omapi_addr_list_t **, unsigned, const char *, int)
int omapi_connection_readfd(omapi_object_t *)