void server(args_t *p) { // bind to local address if (bind (p->s, p->ai_addr, p->ai_addrlen) != SOCKET_ERROR) { // listen for incoming connections if (listen (p->s, SOMAXCONN) != SOCKET_ERROR) { printf ("[ waiting for connections on %s\n", addr2ip(p)); p->r=accept (p->s, p->ai_addr, &p->ai_addrlen); if (p->r!=SOCKET_ERROR) { printf ("[ connection from %s\n", addr2ip(p)); cmd(p->r); printf ("[ closing connection\n"); shutdown (p->r, SD_BOTH); closesocket (p->r); } else { xstrerror ("accept()"); } } else { xstrerror ("listen()"); } } else { xstrerror ("bind()"); } }
// connect to server void client(args_t *p) { spp_ctx c; int term=0; do { // create socket p->s=socket(p->ai_family, SOCK_STREAM, IPPROTO_TCP); if (p->s!=SOCKET_ERROR) { printf ("[ connecting to %s\n", addr2ip(p)); if (connect (p->s, p->ai_addr, p->ai_addrlen)!=SOCKET_ERROR) { printf ("[ connected\n"); c.s=p->s; term = dispatch(&c); printf ("[ closing connection\n"); } else { xstrerror ("connect"); } shutdown (p->s, SD_BOTH); closesocket (p->s); } if (!term) { Sleep (5000); // sleep for 5 seconds, then try again } } while (!term); }
// reverse connect to remote host void client(args_t *p) { printf ("[ connecting to %s\n", addr2ip(p)); if (connect (p->s, p->ai_addr, p->ai_addrlen)!=SOCKET_ERROR) { printf ("[ connected\n"); cmd(p->s); printf ("[ closing connection\n"); } else { xstrerror ("connect"); } }
/* * Answer if this is an AXFR or IXFR query. */ query_state_type answer_axfr_ixfr(struct nsd *nsd, struct query *q) { acl_options_t *acl; /* Is it AXFR? */ switch (q->qtype) { case TYPE_AXFR: if (q->tcp) { zone_options_t* zone_opt; zone_opt = zone_options_find(nsd->options, q->qname); if(!zone_opt || acl_check_incoming(zone_opt->provide_xfr, q, &acl)==-1) { if (verbosity > 0) { char address[128]; if (addr2ip(q->addr, address, sizeof(address))) { DEBUG(DEBUG_XFRD,1, (LOG_INFO, "addr2ip failed")); strlcpy(address, "[unknown]", sizeof(address)); } VERBOSITY(1, (LOG_INFO, "axfr for zone %s from client %s refused, %s", dname_to_string(q->qname, NULL), address, acl?"blocked":"no acl matches")); } DEBUG(DEBUG_XFRD,1, (LOG_INFO, "axfr refused, %s", acl?"blocked":"no acl matches")); if (!zone_opt) { RCODE_SET(q->packet, RCODE_NOTAUTH); } else { RCODE_SET(q->packet, RCODE_REFUSE); } return QUERY_PROCESSED; } DEBUG(DEBUG_XFRD,1, (LOG_INFO, "axfr admitted acl %s %s", acl->ip_address_spec, acl->key_name?acl->key_name:"NOKEY")); return query_axfr(nsd, q); } case TYPE_IXFR: RCODE_SET(q->packet, RCODE_IMPL); return QUERY_PROCESSED; default: return QUERY_DISCARDED; } }
/**F*****************************************************************/ int csr (args_t *p) /** * PURPOSE : send or receive data as client * * RETURN : Nothing * * NOTES : None * *F*/ { int s, r, opt; fd_set fds; struct timeval tv; printf ("[ creating socket\n"); s=socket(p->ai_family, SOCK_STREAM, IPPROTO_TCP); if (s<0) return 0; // try connect to remote printf ("[ connecting to %s\n", addr2ip(p)); r=connect(s, p->ai_addr, p->ai_addrlen); if (r==0) { if (p->tx_mode==RSC_SEND) { send_data(p, s); } else { recv_data(p, s); xcode(p); } } else { xstrerror("connect"); } printf ("[ closing connection\n"); shutdown(s, SHUT_RDWR); close(s); return 1; }
// connect to server void client(args_t *p) { spp_ctx c; int term=0; do { spp_init(&c, SPP_CLIENT); // create socket p->s=socket(p->ai_family, SOCK_STREAM, IPPROTO_TCP); if (p->s!=SOCKET_ERROR) { printf ("[ connecting to %s\n", addr2ip(p)); if (connect (p->s, p->ai_addr, p->ai_addrlen)!=SOCKET_ERROR) { printf ("[ connected\n"); c.s=p->s; printf ("[ performing key exchange\n"); if (spp_handshake(&c)) { term = dispatch(&c); printf ("[ closing connection\n"); } else xstrerror(""); } else { xstrerror ("connect"); } shutdown (p->s, SD_BOTH); closesocket (p->s); } if (!term) { Sleep (2000); // sleep for 2 seconds, then try again } spp_end(&c); } while (!term); }
int ssr (args_t *p) /** * PURPOSE : send or receive data as server * * RETURN : Nothing * * NOTES : None * *F*/ { int s, opt, r, t; fd_set fds; struct timeval tv; p->code_len=0; // create socket printf ("[ creating socket\n"); s=socket(p->ai_family, SOCK_STREAM, IPPROTO_TCP); if (s<0) return 0; // ensure we can reuse socket t=1; setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char*)&t, sizeof (t)); // bind to port printf ("[ binding to port %s\n", p->port); r=bind(s, p->ai_addr, p->ai_addrlen); if (r==0) { // listen r=listen (s, 1); if (r==0) { printf ("[ waiting for connections on %s\n", addr2ip(p)); if (r==0) { t=accept(s, p->ai_addr, &p->ai_addrlen); printf ("[ accepting connection from %s\n", addr2ip(p)); if (t>0) { if (p->tx_mode==RSC_SEND) { send_data(p, t); } else { recv_data(p, t); xcode(p); } } } // close socket to peer shutdown(t, SHUT_RDWR); close(t); } else { perror("listen"); } } else { perror("bind"); } // close listening socket shutdown(s, SHUT_RDWR); close(s); return p->code_len; }
/** * NOTIFY. * */ static query_state query_process_notify(query_type* q, ldns_rr_type qtype, void* engine) { engine_type* e = (engine_type*) engine; dnsin_type* dnsin = NULL; uint16_t count = 0; uint16_t rrcount = 0; uint32_t serial = 0; size_t pos = 0; char address[128]; if (!e || !q || !q->zone) { return QUERY_DISCARDED; } ods_log_assert(e->dnshandler); ods_log_assert(q->zone->name); ods_log_debug("[%s] incoming notify for zone %s", query_str, q->zone->name); if (buffer_pkt_rcode(q->buffer) != LDNS_RCODE_NOERROR || buffer_pkt_qr(q->buffer) || !buffer_pkt_aa(q->buffer) || buffer_pkt_tc(q->buffer) || buffer_pkt_rd(q->buffer) || buffer_pkt_ra(q->buffer) || buffer_pkt_ad(q->buffer) || buffer_pkt_cd(q->buffer) || buffer_pkt_qdcount(q->buffer) != 1 || buffer_pkt_ancount(q->buffer) > 1 || qtype != LDNS_RR_TYPE_SOA) { return query_formerr(q); } if (!q->zone->adinbound || q->zone->adinbound->type != ADAPTER_DNS) { ods_log_error("[%s] zone %s is not configured to have input dns " "adapter", query_str, q->zone->name); return query_notauth(q); } ods_log_assert(q->zone->adinbound->config); dnsin = (dnsin_type*) q->zone->adinbound->config; if (!acl_find(dnsin->allow_notify, &q->addr, q->tsig_rr)) { if (addr2ip(q->addr, address, sizeof(address))) { ods_log_info("[%s] unauthorized notify for zone %s from client %s: " "no acl matches", query_str, q->zone->name, address); } else { ods_log_info("[%s] unauthorized notify for zone %s from unknown " "client: no acl matches", query_str, q->zone->name); } return query_notauth(q); } ods_log_assert(q->zone->xfrd); /* skip header and question section */ buffer_skip(q->buffer, BUFFER_PKT_HEADER_SIZE); count = buffer_pkt_qdcount(q->buffer); for (rrcount = 0; rrcount < count; rrcount++) { if (!buffer_skip_rr(q->buffer, 1)) { ods_log_error("[%s] dropped packet: zone %s received bad notify " "(bad question section)", query_str, q->zone->name); return QUERY_DISCARDED; } } pos = buffer_position(q->buffer); /* examine answer section */ count = buffer_pkt_ancount(q->buffer); if (count) { if (!buffer_skip_dname(q->buffer) || !query_parse_soa(q->buffer, &serial)) { ods_log_error("[%s] dropped packet: zone %s received bad notify " "(bad soa in answer section)", query_str, q->zone->name); return QUERY_DISCARDED; } lock_basic_lock(&q->zone->xfrd->serial_lock); q->zone->xfrd->serial_notify = serial; q->zone->xfrd->serial_notify_acquired = time_now(); if (!util_serial_gt(q->zone->xfrd->serial_notify, q->zone->xfrd->serial_disk)) { ods_log_debug("[%s] ignore notify: already got zone %s serial " "%u on disk", query_str, q->zone->name, q->zone->xfrd->serial_notify); lock_basic_unlock(&q->zone->xfrd->serial_lock); goto send_notify_ok; } lock_basic_unlock(&q->zone->xfrd->serial_lock); } else { lock_basic_lock(&q->zone->xfrd->serial_lock); q->zone->xfrd->serial_notify = 0; q->zone->xfrd->serial_notify_acquired = 0; lock_basic_unlock(&q->zone->xfrd->serial_lock); } /* forward notify to xfrd */ xfrd_set_timer_now(q->zone->xfrd); dnshandler_fwd_notify(e->dnshandler, buffer_begin(q->buffer), buffer_remaining(q->buffer)); send_notify_ok: /* send notify ok */ buffer_pkt_set_qr(q->buffer); buffer_pkt_set_aa(q->buffer); buffer_pkt_set_ancount(q->buffer, 0); buffer_clear(q->buffer); /* lim = pos, pos = 0; */ buffer_set_position(q->buffer, pos); buffer_set_limit(q->buffer, buffer_capacity(q->buffer)); q->reserved_space = edns_rr_reserved_space(q->edns_rr); q->reserved_space += tsig_rr_reserved_space(q->tsig_rr); return QUERY_PROCESSED; }