return d;
}
+guint8 *flx_dns_packet_append_uint32(flxDnsPacket *p, guint32 v) {
+ guint8 *d;
+
+ g_assert(p);
+ d = flx_dns_packet_extend(p, sizeof(guint32));
+ *((guint32*) d) = g_htonl(v);
+
+ return d;
+}
+
+guint8 *flx_dns_packet_append_bytes(flxDnsPacket *p, gconstpointer b, guint l) {
+ guint8* d;
+
+ g_assert(p);
+ g_assert(b);
+ g_assert(l);
+
+ d = flx_dns_packet_extend(p, l);
+ g_assert(d);
+ memcpy(d, b, l);
+
+ return d;
+}
+
+
guint8 *flx_dns_packet_extend(flxDnsPacket *p, guint l) {
guint8 *d;
}
guint8* flx_dns_packet_append_record(flxDnsPacket *p, flxRecord *r, gboolean cache_flush) {
+ guint8 *t;
-
+ g_assert(p);
+ g_assert(r);
+
+ if (!(t = flx_dns_packet_append_name(p, r->key->name)) ||
+ !flx_dns_packet_append_uint16(p, r->key->type) ||
+ !flx_dns_packet_append_uint16(p, cache_flush ? (r->key->class | MDNS_CACHE_FLUSH) : (r->key->class &~ MDNS_CACHE_FLUSH)) ||
+ !flx_dns_packet_append_uint32(p, r->ttl) ||
+ !flx_dns_packet_append_uint16(p, r->size) ||
+ !flx_dns_packet_append_bytes(p, r->data, r->size))
+ return NULL;
+
+ return t;
}
void flx_dns_packet_set_field(flxDnsPacket *p, guint index, guint16 v);
guint16 flx_dns_packet_get_field(flxDnsPacket *p, guint index);
+guint8 *flx_dns_packet_extend(flxDnsPacket *p, guint l);
+
guint8 *flx_dns_packet_append_uint16(flxDnsPacket *p, guint16 v);
+guint8 *flx_dns_packet_append_uint32(flxDnsPacket *p, guint32 v);
guint8 *flx_dns_packet_append_name(flxDnsPacket *p, const gchar *name);
guint8 *flx_dns_packet_append_name_compressed(flxDnsPacket *p, const gchar *name, guint8 *prev);
-guint8 *flx_dns_packet_extend(flxDnsPacket *p, guint l);
+guint8 *flx_dns_packet_append_bytes(flxDnsPacket *p, gconstpointer, guint l);
+guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k);
+guint8* flx_dns_packet_append_record(flxDnsPacket *p, flxRecord *r, gboolean cache_flush);
+
gint flx_dns_packet_is_query(flxDnsPacket *p);
gint flx_dns_packet_check_valid(flxDnsPacket *p);
-gint flx_dns_packet_consume_name(flxDnsPacket *p, gchar *ret_name, guint l);
gint flx_dns_packet_consume_uint16(flxDnsPacket *p, guint16 *ret_v);
gint flx_dns_packet_consume_uint32(flxDnsPacket *p, guint32 *ret_v);
+gint flx_dns_packet_consume_name(flxDnsPacket *p, gchar *ret_name, guint l);
gint flx_dns_packet_consume_bytes(flxDnsPacket *p, gpointer ret_data, guint l);
+flxKey* flx_dns_packet_consume_key(flxDnsPacket *p);
+flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_flush);
gconstpointer flx_dns_packet_get_rptr(flxDnsPacket *p);
-flxKey* flx_dns_packet_consume_key(flxDnsPacket *p);
-flxRecord* flx_dns_packet_consume_record(flxDnsPacket *p, gboolean *ret_cache_flush);
-guint8* flx_dns_packet_append_key(flxDnsPacket *p, flxKey *k);
-guint8* flx_dns_packet_append_record(flxDnsPacket *p, flxRecord *r, gboolean cache_flush);
gint flx_dns_packet_skip(flxDnsPacket *p, guint length);
flx_interface_is_relevant(a->interface);
}
-void flx_interface_send_query(flxInterface *i, guchar protocol, flxKey *k) {
- flxDnsPacket *p;
+void flx_interface_send_packet(flxInterface *i, guchar protocol, flxDnsPacket *p) {
g_assert(i);
- g_assert(k);
-
- p = flx_dns_packet_new();
- flx_dns_packet_set_field(p, DNS_FIELD_FLAGS, DNS_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
-
- flx_dns_packet_append_name(p, k->name);
- flx_dns_packet_append_uint16(p, k->type);
- flx_dns_packet_append_uint16(p, k->class);
-
- flx_dns_packet_set_field(p, DNS_FIELD_QDCOUNT, 1);
-
+ g_assert(p);
+
if ((protocol == AF_INET || protocol == AF_UNSPEC) && i->n_ipv4_addrs > 0 && flx_interface_is_relevant(i)) {
g_message("sending on '%s':IPv4", i->name);
flx_send_dns_packet_ipv4(i->monitor->server->fd_ipv4, i->index, p);
g_message("sending on '%s':IPv6", i->name);
flx_send_dns_packet_ipv6(i->monitor->server->fd_ipv6, i->index, p);
}
+}
+
+void flx_interface_send_query(flxInterface *i, guchar protocol, flxKey *k) {
+ flxDnsPacket *p;
+ g_assert(i);
+ g_assert(k);
+
+ p = flx_dns_packet_new();
+ flx_dns_packet_set_field(p, DNS_FIELD_FLAGS, DNS_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ flx_dns_packet_append_key(p, k);
+ flx_dns_packet_set_field(p, DNS_FIELD_QDCOUNT, 1);
+ flx_interface_send_packet(i, protocol, p);
flx_dns_packet_free(p);
}
-void flx_interface_send_response(flxinterface *i, guchar protocol, flxRecord *rr) {
- flxDnsPacket+p;
+void flx_interface_send_response(flxInterface *i, guchar protocol, flxRecord *rr) {
+ flxDnsPacket *p;
g_assert(i);
g_assert(rr);
p = flx_dns_packet_new();
flx_dns_packet_set_field(p, DNS_FIELD_FLAGS, DNS_FLAGS(1, 0, 0, 0, 0, 0, 0, 0, 0, 0));
-
- flx_dns_packet_append_name(p, rr->key->name);
- flx_dns_packet_append_uint16(p, rr->key->type);
- flx_dns_packet_append_uint16(p, rr->key->class);
- flx_dns_packet_append_uint16
+ flx_dns_packet_append_record(p, rr, FALSE);
+ flx_dns_packet_set_field(p, DNS_FIELD_ANCOUNT, 1);
+ flx_interface_send_packet(i, protocol, p);
+ flx_dns_packet_free(p);
}
-
-
void flx_dump_caches(flxServer *s, FILE *f) {
flxInterface *i;
g_assert(s);
int flx_address_is_relevant(flxInterfaceAddress *a);
void flx_interface_send_query(flxInterface *i, guchar protocol, flxKey *k);
+void flx_interface_send_response(flxInterface *i, guchar protocol, flxRecord *rr);
void flx_dump_caches(flxServer *s, FILE *f);
flxServer *flx = data;
flxKey *k;
+ flx_server_dump(flx, stdout);
+
+
k = flx_key_new("cocaine.local.", FLX_DNS_CLASS_IN, FLX_DNS_TYPE_A);
flx_server_send_query(flx, 0, AF_UNSPEC, k);
flx_key_unref(k);
loop = g_main_loop_new(NULL, FALSE);
- g_timeout_add(1000*5, quit_timeout, loop);
+ /*g_timeout_add(1000*5, quit_timeout, loop);*/
g_timeout_add(1000, send_timeout, flx);
g_main_loop_run(loop);
g_main_loop_unref(loop);
- flx_server_dump(flx, stdout);
flx_server_free(flx);
#include "socket.h"
static void post_response(flxServer *s, flxRecord *r, gint iface, const flxAddress *a) {
+ flxInterface *i;
+
+ g_assert(s);
+ g_assert(r);
+ g_assert(iface > 0);
+ g_assert(a);
+
+ if ((i = flx_interface_monitor_get_interface(s->monitor, iface)))
+ flx_interface_send_response(i, a->family, r);
+
}
static void handle_query_key(flxServer *s, flxKey *k, gint iface, const flxAddress *a) {
g_assert(k);
g_assert(a);
- for (e = g_hash_table_lookup(s->rrset_by_name, k); e; e = e->next_by_name) {
+ for (e = g_hash_table_lookup(s->rrset_by_name, k); e; e = e->by_name_next) {
if ((e->interface <= 0 || e->interface == iface) &&
- (e->protocol == AF_UNSPEC || e->protocol == a->family))
+ (e->protocol == AF_UNSPEC || e->protocol == a->family)) {
post_response(s, e->record, iface, a);
+
+ }
}
}
flxKey *key;
- if (!(key = flx_dns_packet_consume_query(p))) {
+ if (!(key = flx_dns_packet_consume_key(p))) {
g_warning("Packet too short");
return;
}
flxRecord *rr;
gboolean cache_flush = FALSE;
- if (!(rr = flx_dns_packet_consume_rr(p, &cache_flush))) {
+ if (!(rr = flx_dns_packet_consume_record(p, &cache_flush))) {
g_warning("Packet too short");
return;
}
g_assert(sa);
g_assert(iface > 0);
+ g_message("new packet recieved.");
+
if (!(i = flx_interface_monitor_get_interface(s->monitor, iface))) {
g_warning("Recieved packet from invalid interface.");
return;
if (flx_dns_packet_is_query(p)) {
if (flx_dns_packet_get_field(p, DNS_FIELD_QDCOUNT) == 0 ||
- flx_dns_packet_get_field(p, DNS_FIELD_ARCOUNT) != 0
+ flx_dns_packet_get_field(p, DNS_FIELD_ARCOUNT) != 0 ||
flx_dns_packet_get_field(p, DNS_FIELD_NSCOUNT) != 0) {
g_warning("Invalid query packet.");
return;
gint flx_open_socket_ipv4(void) {
struct ip_mreqn mreq;
struct sockaddr_in sa, local;
- int fd = -1, ttl, yes, no;
+ int fd = -1, ttl, yes;
mdns_mcast_group_ipv4(&sa);
goto fail;
}
- no = 0;
- if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &no, sizeof(no)) < 0) {
+ yes = 1;
+ if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
g_warning("IP_MULTICAST_LOOP failed: %s\n", strerror(errno));
goto fail;
}
gint flx_open_socket_ipv6(void) {
struct ipv6_mreq mreq;
struct sockaddr_in6 sa, local;
- int fd = -1, ttl, yes, no;
+ int fd = -1, ttl, yes;
mdns_mcast_group_ipv6(&sa);
goto fail;
}
- no = 0;
- if (setsockopt(fd, SOL_IPV6, IPV6_MULTICAST_LOOP, &no, sizeof(no)) < 0) {
+ yes = 1;
+ if (setsockopt(fd, SOL_IPV6, IPV6_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
g_warning("IPV6_MULTICAST_LOOP failed: %s\n", strerror(errno));
goto fail;
}