34 #include <arpa/inet.h> 39 static void trace_connect_input (
trace_type_t *,
unsigned,
char *);
41 static void trace_disconnect_input (
trace_type_t *,
unsigned,
char *);
47 static isc_result_t omapi_connection_connect_internal (
omapi_object_t *);
53 const char *server_name,
63 log_debug (
"omapi_connect(%s, port=%d)", server_name, port);
66 if (!inet_aton (server_name, &foo)) {
69 he = gethostbyname (server_name);
72 for (i = 0; he -> h_addr_list [i]; i++)
79 if (status != ISC_R_SUCCESS)
81 for (i = 0; i < hix; i++) {
82 addrs -> addresses [i].addrtype = he -> h_addrtype;
83 addrs -> addresses [i].addrlen = he -> h_length;
84 memcpy (addrs -> addresses [i].address,
85 he -> h_addr_list [i],
86 (
unsigned)he -> h_length);
87 addrs -> addresses [i].port = port;
91 if (status != ISC_R_SUCCESS)
93 addrs -> addresses [0].addrtype = AF_INET;
94 addrs -> addresses [0].addrlen =
sizeof foo;
95 memcpy (addrs -> addresses [0].address, &foo,
sizeof foo);
96 addrs -> addresses [0].port = port;
110 struct sockaddr_in local_sin;
113 status = omapi_connection_allocate (&obj,
MDL);
114 if (status != ISC_R_SUCCESS)
119 if (status != ISC_R_SUCCESS) {
120 omapi_connection_dereference (&obj,
MDL);
124 if (status != ISC_R_SUCCESS) {
125 omapi_connection_dereference (&obj,
MDL);
134 #if defined (TRACING) 141 socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
142 if (obj -> socket < 0) {
143 omapi_connection_dereference (&obj,
MDL);
144 if (errno == EMFILE || errno == ENFILE
146 return ISC_R_NORESOURCES;
147 return ISC_R_UNEXPECTED;
153 if (local_addr -> addrtype != AF_INET) {
155 omapi_connection_dereference (&obj,
MDL);
158 local_sin.sin_port = htons (local_addr -> port);
159 memcpy (&local_sin.sin_addr,
160 local_addr -> address,
161 local_addr -> addrlen);
162 #if defined (HAVE_SA_LEN) 163 local_sin.sin_len =
sizeof local_addr;
165 local_sin.sin_family = AF_INET;
166 memset (&local_sin.sin_zero, 0,
167 sizeof local_sin.sin_zero);
169 if (bind (obj -> socket, (
struct sockaddr *)&local_sin,
170 sizeof local_sin) < 0) {
175 if (errno == EADDRINUSE)
176 return ISC_R_ADDRINUSE;
177 if (errno == EADDRNOTAVAIL)
178 return ISC_R_ADDRNOTAVAIL;
181 return ISC_R_UNEXPECTED;
183 obj -> local_addr = local_sin;
187 if (fcntl (obj -> socket, F_SETFD, 1) < 0) {
188 close (obj -> socket);
189 omapi_connection_dereference (&obj,
MDL);
190 return ISC_R_UNEXPECTED;
196 if (setsockopt (obj -> socket, SOL_SOCKET, SO_REUSEADDR,
197 (
char *)&flag,
sizeof flag) < 0) {
198 omapi_connection_dereference (&obj,
MDL);
199 return ISC_R_UNEXPECTED;
203 if (fcntl (obj -> socket, F_SETFL, O_NONBLOCK) < 0) {
204 omapi_connection_dereference (&obj,
MDL);
205 return ISC_R_UNEXPECTED;
214 if (setsockopt(obj->socket, SOL_SOCKET, SO_NOSIGPIPE,
215 (
char *)&flag,
sizeof(flag)) < 0) {
216 omapi_connection_dereference (&obj,
MDL);
217 return ISC_R_UNEXPECTED;
226 if (status != ISC_R_SUCCESS)
237 if (status == ISC_R_INPROGRESS) {
238 status = ISC_R_SUCCESS;
240 #if defined (TRACING) 246 omapi_connection_dereference (&obj,
MDL);
250 #if defined (TRACING) 258 trace_connect_stop,
MDL);
260 trace_disconnect_input,
261 trace_disconnect_stop,
MDL);
270 int32_t connect_index, listener_index;
271 static int32_t index;
273 if (!omapi_connections) {
274 status = omapi_connection_array_allocate (&omapi_connections,
276 if (status != ISC_R_SUCCESS)
280 status = omapi_connection_array_extend (omapi_connections, obj,
282 if (status != ISC_R_SUCCESS) {
287 #if defined (TRACING) 298 connect_index = htonl (index);
301 listener_index = htonl (obj -> listener -> index);
303 listener_index = htonl (-1);
304 iov [iov_count].
buf = (
char *)&connect_index;
305 iov [iov_count++].
len =
sizeof connect_index;
306 iov [iov_count].
buf = (
char *)&listener_index;
307 iov [iov_count++].
len =
sizeof listener_index;
308 iov [iov_count].
buf = (
char *)&obj -> remote_addr.sin_port;
309 iov [iov_count++].len =
sizeof obj -> remote_addr.sin_port;
310 iov [iov_count].buf = (
char *)&obj -> local_addr.sin_port;
311 iov [iov_count++].
len =
sizeof obj -> local_addr.sin_port;
312 iov [iov_count].
buf = (
char *)&obj -> remote_addr.sin_addr;
313 iov [iov_count++].len =
sizeof obj -> remote_addr.sin_addr;
314 iov [iov_count].buf = (
char *)&obj -> local_addr.sin_addr;
315 iov [iov_count++].
len =
sizeof obj -> local_addr.sin_addr;
324 unsigned length,
char *buf)
326 struct sockaddr_in remote, local;
327 int32_t connect_index, listener_index;
333 if (length != ((
sizeof connect_index) +
334 (
sizeof remote.sin_port) +
335 (
sizeof remote.sin_addr)) * 2) {
336 log_error (
"Trace connect: invalid length %d", length);
340 memset (&remote, 0,
sizeof remote);
341 memset (&local, 0,
sizeof local);
342 memcpy (&connect_index, s,
sizeof connect_index);
343 s +=
sizeof connect_index;
344 memcpy (&listener_index, s,
sizeof listener_index);
345 s +=
sizeof listener_index;
346 memcpy (&remote.sin_port, s,
sizeof remote.sin_port);
347 s +=
sizeof remote.sin_port;
348 memcpy (&local.sin_port, s,
sizeof local.sin_port);
349 s +=
sizeof local.sin_port;
350 memcpy (&remote.sin_addr, s,
sizeof remote.sin_addr);
351 s +=
sizeof remote.sin_addr;
352 memcpy (&local.sin_addr, s,
sizeof local.sin_addr);
353 s +=
sizeof local.sin_addr;
356 connect_index = ntohl (connect_index);
357 listener_index = ntohl (listener_index);
361 if (listener_index != -1) {
366 if (lp -> address.sin_port == local.sin_port) {
367 omapi_listener_reference (&listener, lp,
MDL);
368 omapi_listener_dereference (&lp,
MDL);
375 "Spurious traced listener connect - index ",
376 (
long int)listener_index,
377 inet_ntoa (local.sin_addr),
378 ntohs (local.sin_port));
383 if (status != ISC_R_SUCCESS) {
384 log_error (
"traced listener connect: %s",
385 isc_result_totext (status));
388 omapi_connection_dereference (&obj,
MDL);
389 omapi_listener_dereference (&listener,
MDL);
396 for (i = 0; (lp->connect_list &&
397 i < lp->connect_list->count); i++) {
398 if (!memcmp (&remote.sin_addr,
399 &lp->connect_list->addresses[i].address,
400 sizeof remote.sin_addr) &&
401 (ntohs (remote.sin_port) ==
402 lp->connect_list->addresses[i].port)) {
404 lp->remote_addr = remote;
405 lp->remote_addr.sin_family = AF_INET;
407 lp->index = connect_index;
410 omapi_connection_dereference (&lp,
MDL);
417 log_error (
"Spurious traced connect - index %ld, addr %s, port %d",
418 (
long int)connect_index, inet_ntoa (remote.sin_addr),
419 ntohs (remote.sin_port));
423 static void trace_connect_stop (
trace_type_t *ttype) { }
425 static void trace_disconnect_input (
trace_type_t *ttype,
426 unsigned length,
char *buf)
429 if (length !=
sizeof *index) {
430 log_error (
"trace disconnect: wrong length %d", length);
434 index = (int32_t *)buf;
438 if (lp -> index == ntohl (*index)) {
440 omapi_connection_dereference (&lp,
MDL);
446 log_error (
"trace disconnect: no connection matching index %ld",
447 (
long int)ntohl (*index));
450 static void trace_disconnect_stop (
trace_type_t *ttype) { }
462 #ifdef DEBUG_PROTOCOL 463 log_debug (
"omapi_disconnect(%s)", force ?
"force" :
"");
470 #if defined (TRACING) 475 index = htonl (c -> index);
477 sizeof index, (
char *)&index,
479 if (status != ISC_R_SUCCESS) {
482 isc_result_totext (status));
491 return ISC_R_SUCCESS;
498 if (!shutdown (c -> socket,
SHUT_RD)) {
499 if (c -> out_bytes > 0) {
502 return ISC_R_SUCCESS;
507 #if defined (TRACING) 524 if (h -> outer -> inner)
539 if (h->inner != NULL) {
540 if (h->inner->outer != NULL) {
559 return ISC_R_SUCCESS;
570 c -> bytes_needed = bytes;
571 if (c -> bytes_needed <= c -> in_bytes) {
572 return ISC_R_SUCCESS;
617 status = omapi_connection_connect_internal (h);
618 if (status == ISC_R_INPROGRESS)
619 return ISC_R_INPROGRESS;
621 if (status != ISC_R_SUCCESS)
624 return ISC_R_SUCCESS;
627 static isc_result_t omapi_connection_connect_internal (
omapi_object_t *h)
640 if (getsockopt (c -> socket, SOL_SOCKET, SO_ERROR,
641 (
char *)&error, &sl) < 0) {
643 return ISC_R_SUCCESS;
650 if (c -> cptr >= c -> connect_list -> count) {
653 status = ISC_R_CONNREFUSED;
656 status = ISC_R_NETUNREACH;
666 if (c -> connect_list -> addresses [c -> cptr].addrtype !=
672 memcpy (&c -> remote_addr.sin_addr,
673 &c -> connect_list -> addresses [c -> cptr].address,
674 sizeof c -> remote_addr.sin_addr);
675 c -> remote_addr.sin_family = AF_INET;
676 c -> remote_addr.sin_port =
677 htons (c -> connect_list -> addresses [c -> cptr].port);
678 #if defined (HAVE_SA_LEN) 679 c -> remote_addr.sin_len =
sizeof c -> remote_addr;
681 memset (&c -> remote_addr.sin_zero, 0,
682 sizeof c -> remote_addr.sin_zero);
685 error = connect (c -> socket,
686 (
struct sockaddr *)&c -> remote_addr,
687 sizeof c -> remote_addr);
690 if (error != EINPROGRESS) {
694 status = ISC_R_CONNREFUSED;
697 status = ISC_R_NETUNREACH;
713 sl =
sizeof (c -> local_addr);
714 if (getsockname (c -> socket,
715 (
struct sockaddr *)&c -> local_addr, &sl) < 0) {
729 if (status != ISC_R_SUCCESS) {
736 return ISC_R_INPROGRESS;
752 c -> out_bytes == 0) {
753 #ifdef DEBUG_PROTOCOL 754 log_debug (
"omapi_connection_reaper(): disconnect");
759 #ifdef DEBUG_PROTOCOL 760 log_debug (
"omapi_connection_reaper(): closed");
762 return ISC_R_NOTCONNECTED;
764 return ISC_R_SUCCESS;
771 char *name_str = NULL;
772 isc_result_t status = ISC_R_SUCCESS;
774 if (status == ISC_R_SUCCESS)
778 if (status == ISC_R_SUCCESS)
782 if (status == ISC_R_SUCCESS)
786 if (status == ISC_R_SUCCESS) {
796 if (status == ISC_R_SUCCESS) {
797 name_str =
dmalloc (name -> value -> u.buffer.len + 1,
MDL);
799 status = ISC_R_NOMEMORY;
802 if (status == ISC_R_SUCCESS) {
804 name -> value -> u.buffer.value,
805 name -> value -> u.buffer.len);
806 name_str [name -> value -> u.buffer.len] = 0;
815 status = ISC_R_NOMEMORY;
833 const unsigned char *data,
839 dst_context_t **dctx = (dst_context_t **)context;
844 if (status != ISC_R_SUCCESS) {
852 region.base = (
unsigned char *)data;
854 dst_context_adddata(*dctx, ®ion);
859 unsigned int sigsize;
862 status = dst_key_sigsize(key, &sigsize);
863 if (status != ISC_R_SUCCESS) {
870 if (status != ISC_R_SUCCESS) {
875 status = dst_context_sign(*dctx, &sigbuf);
876 if (status != ISC_R_SUCCESS) {
891 dst_context_destroy(dctx);
895 return ISC_R_SUCCESS;
908 return ISC_R_NOTFOUND;
910 return(dst_key_sigsize(c->
out_key, l));
929 if (c -> in_context) {
942 status = make_dst_key (&c -> in_key,
944 if (status != ISC_R_SUCCESS)
948 return ISC_R_SUCCESS;
954 if (c -> out_context) {
967 status = make_dst_key (&c -> out_key,
969 if (status != ISC_R_SUCCESS)
973 return ISC_R_SUCCESS;
976 if (h -> inner && h -> inner -> type -> set_value)
977 return (*(h -> inner -> type -> set_value))
978 (h -> inner, id, name, value);
979 return ISC_R_NOTFOUND;
990 unsigned int sigsize;
997 if (!c -> in_key || !c -> in_context)
998 return ISC_R_NOTFOUND;
1004 if (status != ISC_R_SUCCESS)
1013 return ISC_R_NOTFOUND;
1015 status = dst_key_sigsize(c->
in_key, &sigsize);
1016 if (status != ISC_R_SUCCESS) {
1023 if (!c -> out_key || !c -> out_context)
1024 return ISC_R_NOTFOUND;
1030 if (status != ISC_R_SUCCESS)
1039 return ISC_R_NOTFOUND;
1042 status = dst_key_sigsize(c->
out_key, &sigsize);
1043 if (status != ISC_R_SUCCESS) {
1050 if (h -> inner && h -> inner -> type -> get_value)
1051 return (*(h -> inner -> type -> get_value))
1052 (h -> inner, id, name, value);
1053 return ISC_R_NOTFOUND;
1061 #ifdef DEBUG_PROTOCOL 1062 log_debug (
"omapi_connection_destroy()");
1066 return ISC_R_UNEXPECTED;
1071 omapi_listener_dereference (&c -> listener,
file,
line);
1072 if (c -> connect_list)
1074 return ISC_R_SUCCESS;
1078 const char *name, va_list ap)
1083 #ifdef DEBUG_PROTOCOL 1084 log_debug (
"omapi_connection_signal_handler(%s)", name);
1087 if (h -> inner && h -> inner -> type -> signal_handler)
1088 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
1090 return ISC_R_NOTFOUND;
1103 if (m -> inner && m -> inner -> type -> stuff_values)
1104 return (*(m -> inner -> type -> stuff_values)) (c, id,
1106 return ISC_R_SUCCESS;
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_disconnect(omapi_object_t *h, int force)
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 *)
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)
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
dhcp_context_t dhcp_gbl_ctx
#define DHCP_R_INVALIDARG
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__
#define DHCP_R_HOSTUNKNOWN
void omapi_connection_trace_setup(void)
struct omapi_typed_data_t::@3::@4 buffer
isc_result_t omapi_connection_output_auth_length(omapi_object_t *h, unsigned *l)
isc_result_t omapi_get_value_str(omapi_object_t *, omapi_object_t *, const char *, omapi_value_t **)
isc_result_t omapi_connection_set_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_typed_data_t *value)
OMAPI_OBJECT_ALLOC(omapi_connection, omapi_connection_object_t, omapi_type_connection)
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_connect_list(omapi_object_t *c, omapi_addr_list_t *remote_addrs, omapi_addr_t *local_addr)
isc_result_t omapi_object_dereference(omapi_object_t **, const char *, int)
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_connection_reaper(omapi_object_t *h)
isc_result_t omapi_connection_require(omapi_object_t *h, unsigned bytes)
void dfree(void *, 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_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 omapi_connection_stuff_values(omapi_object_t *c, omapi_object_t *id, omapi_object_t *m)
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
isc_result_t omapi_connection_get_value(omapi_object_t *h, omapi_object_t *id, omapi_data_string_t *name, omapi_value_t **value)
int omapi_ds_strcmp(omapi_data_string_t *, const char *)
isc_result_t omapi_connection_connect(omapi_object_t *h)
isc_result_t omapi_unregister_io_object(omapi_object_t *)
#define omapi_array_foreach_end(array, stype, var)
isc_result_t omapi_connection_signal_handler(omapi_object_t *h, const char *name, va_list ap)
isc_result_t omapi_listener_connect(omapi_connection_object_t **obj, omapi_listener_object_t *listener, int socket, struct sockaddr_in *remote_addr)
#define OMAPI_ARRAY_TYPE(name, stype)
#define DHCP_R_INCOMPLETE
int omapi_connection_readfd(omapi_object_t *h)
isc_result_t trace_write_packet(trace_type_t *, unsigned, const char *, const char *, int)
int omapi_connection_writefd(omapi_object_t *h)
isc_result_t omapi_connection_destroy(omapi_object_t *h, const char *file, int line)
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)