static void set_socks_server(const char *socks) { struct url *url; enum socks_ver socksv; url = url_tokenize(socks); if (!url || !url->scheme) { log_error("shim: bad socks server, %s", socks); exit(1); } if (url->port < 0) url->port = 1080; if (!evutil_ascii_strcasecmp(url->scheme, "socks4")) socksv = SOCKS_4; else if (!evutil_ascii_strcasecmp(url->scheme, "socks4a")) socksv = SOCKS_4a; else { log_error("shim: unknown socks version, %s", url->scheme); exit(1); } if (conn_set_socks_server(url->host, url->port, socksv) < 0) exit(1); url_free(url); }
/** Return true if the list of headers in 'headers', intepreted with respect * to flags, means that we should send a "connection: close" when the request * is done. */ static int evhttp_is_connection_close(int flags, struct evkeyvalq* headers) { if (flags & EVHTTP_PROXY_REQUEST) { /* proxy connection */ const char *connection = evhttp_find_header(headers, "Proxy-Connection"); return (connection == NULL || evutil_ascii_strcasecmp(connection, "keep-alive") != 0); } else { const char *connection = evhttp_find_header(headers, "Connection"); return (connection != NULL && evutil_ascii_strcasecmp(connection, "close") == 0); } }
static void start_listening(struct event_base *base, struct evdns_base *dns, const char *laddr, const char *lport) { struct evutil_addrinfo hints; struct evutil_addrinfo *ai = NULL; int ret; if (!evutil_ascii_strcasecmp(laddr, "any")) laddr = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* turn NULL hostname into INADDR_ANY, and skip looking up any address * types we don't have an interface to connect to. */ hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG; ret = evutil_getaddrinfo(laddr, lport, &hints, &ai); if (ret < 0) { log_error("shim: bad listen address: %s", evutil_gai_strerror(ret)); exit(1); } if (proxy_init(base, dns, ai->ai_addr, ai->ai_addrlen) < 0) exit(1); }
static void fail_server_cb(struct evdns_server_request *req, void *data) { const char *question; int *count = data; struct in_addr in; /* Drop the first N requests that we get. */ if (*count > 0) { --*count; tt_want(! evdns_server_request_drop(req)); return; } if (req->nquestions != 1) TT_DIE(("Only handling one question at a time; got %d", req->nquestions)); question = req->questions[0]->name; if (!evutil_ascii_strcasecmp(question, "google.com")) { /* Detect a probe, and get out of the loop. */ event_base_loopexit(exit_base, NULL); } evutil_inet_pton(AF_INET, "16.32.64.128", &in); evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, 100); tt_assert(! evdns_server_request_respond(req, 0)) return; end: tt_want(! evdns_server_request_drop(req)); }
int main(int argc, char **argv) { struct evdns_base *dns; struct event_base *base; struct bufferevent *bev; struct url *socks, *host; int s4; base = event_base_new(); dns = evdns_base_new(base, 1); log_set_file(NULL); log_set_min_level(LOG_DEBUG); if (argc >= 3) { socks = url_tokenize(argv[2]); s4 = !evutil_ascii_strcasecmp("socks4", socks->scheme); if (conn_set_socks_server(socks->host, socks->port, s4? SOCKS_4 : SOCKS_4a) < 0) return 0; } host = url_connect_tokenize(argv[1]); bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); conn_connect_bufferevent(bev, dns, AF_INET, host->host, host->port, do_connect, NULL); event_base_dispatch(base); return 0; }
void regress_dns_server_cb(struct evdns_server_request *req, void *data) { struct regress_dns_server_table *tab = data; const char *question; if (req->nquestions != 1) TT_DIE(("Only handling one question at a time; got %d", req->nquestions)); question = req->questions[0]->name; while (tab->q && evutil_ascii_strcasecmp(question, tab->q) && strcmp("*", tab->q)) ++tab; if (tab->q == NULL) TT_DIE(("Unexpected question: '%s'", question)); ++tab->seen; if (!strcmp(tab->anstype, "err")) { int err = atoi(tab->ans); tt_assert(! evdns_server_request_respond(req, err)); return; } else if (!strcmp(tab->anstype, "errsoa")) { int err = atoi(tab->ans); char soa_record[] = "\x04" "dns1" "\x05" "icann" "\x03" "org" "\0" "\x0a" "hostmaster" "\x05" "icann" "\x03" "org" "\0" "\x77\xde\x5e\xba" /* serial */ "\x00\x00\x1c\x20" /* refreshtime = 2h */ "\x00\x00\x0e\x10" /* retry = 1h */ "\x00\x12\x75\x00" /* expiration = 14d */ "\x00\x00\x0e\x10" /* min.ttl = 1h */ ; evdns_server_request_add_reply( req, EVDNS_AUTHORITY_SECTION, "example.com", EVDNS_TYPE_SOA, EVDNS_CLASS_INET, 42, sizeof(soa_record) - 1, 0, soa_record); tt_assert(! evdns_server_request_respond(req, err)); return; } else if (!strcmp(tab->anstype, "A")) { struct in_addr in; evutil_inet_pton(AF_INET, tab->ans, &in); evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, 100); } else if (!strcmp(tab->anstype, "AAAA")) { struct in6_addr in6; evutil_inet_pton(AF_INET6, tab->ans, &in6); evdns_server_request_add_aaaa_reply(req, question, 1, &in6.s6_addr, 100); } else { TT_DIE(("Weird table entry with type '%s'", tab->anstype)); } tt_assert(! evdns_server_request_respond(req, 0)) return; end: tt_want(! evdns_server_request_drop(req)); }
/** * @brief guess_type It returns a HTTP type by guessing the file type. * * @param type Input a file type. * * @return Const string of type. */ static const char * guess_type(const char *type) { const struct table_entry *ent; for (ent = &content_type_table[0]; ent->extension; ++ent) { if (!evutil_ascii_strcasecmp(ent->extension, type)) return ent->content_type; } return "application/misc"; }
/* Try to guess a good content-type for 'path' */ static const char *guess_content_type(const char *path) { const char *last_period, *extension; const struct table_entry *ent; last_period = strrchr(path, '.'); if (!last_period || strchr(last_period, '/')) goto not_found; /* no exension */ extension = last_period + 1; for (ent = &content_type_table[0]; ent->extension; ++ent) { if (!evutil_ascii_strcasecmp(ent->extension, extension)) return ent->content_type; } not_found: return "application/octet-stream"; }
static void process_line(struct bufferevent *bev, void *ctx, char *line) { char **argv; int argc = split_args(line, &argv); int i; for (i = 0; cmdlist[i].cmd; i++) if (evutil_ascii_strcasecmp(line, cmdlist[i].cmd) == 0) break; (cmdlist[i].func)(bev, ctx, argc - 1, argv + 1); free(argv); free(line); }
void regress_dns_server_cb(struct evdns_server_request *req, void *data) { struct regress_dns_server_table *tab = data; const char *question; if (req->nquestions != 1) TT_DIE(("Only handling one question at a time; got %d", req->nquestions)); question = req->questions[0]->name; while (tab->q && evutil_ascii_strcasecmp(question, tab->q) && strcmp("*", tab->q)) ++tab; if (tab->q == NULL) TT_DIE(("Unexpected question: '%s'", question)); ++tab->seen; if (!strcmp(tab->anstype, "err")) { int err = atoi(tab->ans); tt_assert(! evdns_server_request_respond(req, err)); return; } else if (!strcmp(tab->anstype, "A")) { struct in_addr in; evutil_inet_pton(AF_INET, tab->ans, &in); evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, 100); } else if (!strcmp(tab->anstype, "AAAA")) { struct in6_addr in6; evutil_inet_pton(AF_INET6, tab->ans, &in6); evdns_server_request_add_aaaa_reply(req, question, 1, &in6.s6_addr, 100); } else { TT_DIE(("Weird table entry with type '%s'", tab->anstype)); } tt_assert(! evdns_server_request_respond(req, 0)) return; end: tt_want(! evdns_server_request_drop(req)); }
static const char* cd_GuessContentType (const char* path) { const char* lastPeriod = strrchr(path, '.'); const char* extension; const CDContentType* type; if (lastPeriod == NULL || strchr(lastPeriod, '/')) { goto end; } extension = lastPeriod + 1; for (type = CDContentTypes; type->extension; type++) { if (!evutil_ascii_strcasecmp(type->extension, extension)) { return type->mime; } } end: { return "application/octet-stream"; } }
/* Try to guess a good content-type for 'path' */ static const char *guess_mime_type(const char *path) { char buf[12] = {0}; char *pos = NULL; const char *last_period, *extension; const struct table_entry *ent; last_period = strrchr(path, '.'); if (!last_period || strchr(last_period, '/')) goto not_found; /* no exension */ extension = last_period + 1; strncpy(buf, extension, sizeof(buf)-1); pos = strpbrk(buf, "?#"); if (pos) *pos = '\0'; for (ent = &content_type_table[0]; ent->extension; ++ent) { if (!evutil_ascii_strcasecmp(ent->extension, buf)) return ent->content_type; } not_found: return "application/octet-stream"; }
tt_str_op(buf, ==, "-200000000000"); tt_int_op(r, ==, 13); r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT, EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize)); tt_str_op(buf, ==, "8000 -9000"); tt_int_op(r, ==, 10); end: ; } static void test_evutil_casecmp(void *ptr) { tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0); tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0); tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0); tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0); tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0); tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0); tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0); tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0); tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0); tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0); tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0); tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0); tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0); end: ;
static int options_parse_resolver(ProxyContext * const proxy_context, char * const * const headers, const size_t headers_count, char * const * const cols, const size_t cols_count) { const char *dnssec; const char *namecoin; const char *nologs; const char *provider_name; const char *provider_publickey_s; const char *resolver_ip; const char *resolver_name; resolver_name = options_get_col(headers, headers_count, cols, cols_count, "Name"); if (resolver_name == NULL) { logger(proxy_context, LOG_ERR, "Invalid resolvers list file: missing 'Name' column"); exit(1); } if (*resolver_name == 0) { logger(proxy_context, LOG_ERR, "Resolver with an empty name"); return -1; } if (evutil_ascii_strcasecmp(resolver_name, proxy_context->resolver_name) != 0) { return 0; } provider_name = options_get_col(headers, headers_count, cols, cols_count, "Provider name"); provider_publickey_s = options_get_col(headers, headers_count, cols, cols_count, "Provider public key"); resolver_ip = options_get_col(headers, headers_count, cols, cols_count, "Resolver address"); if (provider_name == NULL || *provider_name == 0) { logger(proxy_context, LOG_ERR, "Resolvers list is missing a provider name for [%s]", resolver_name); return -1; } if (provider_publickey_s == NULL || *provider_publickey_s == 0) { logger(proxy_context, LOG_ERR, "Resolvers list is missing a public key for [%s]", resolver_name); return -1; } if (resolver_ip == NULL || *resolver_ip == 0) { logger(proxy_context, LOG_ERR, "Resolvers list is missing a resolver address for [%s]", resolver_name); return -1; } dnssec = options_get_col(headers, headers_count, cols, cols_count, "DNSSEC validation"); if (dnssec != NULL && evutil_ascii_strcasecmp(dnssec, "yes") != 0) { logger(proxy_context, LOG_INFO, "- [%s] does not support DNS Security Extensions", resolver_name); } else { logger(proxy_context, LOG_INFO, "+ DNS Security Extensions are supported"); } namecoin = options_get_col(headers, headers_count, cols, cols_count, "Namecoin"); if (namecoin != NULL && evutil_ascii_strcasecmp(namecoin, "yes") == 0) { logger(proxy_context, LOG_INFO, "+ Namecoin domains can be resolved"); } nologs = options_get_col(headers, headers_count, cols, cols_count, "No logs"); if (nologs != NULL && evutil_ascii_strcasecmp(nologs, "no") == 0) { logger(proxy_context, LOG_WARNING, "- [%s] logs your activity - " "a different provider might be better a choice if privacy is a concern", resolver_name); } else { logger(proxy_context, LOG_INFO, "+ Provider supposedly doesn't keep logs"); } proxy_context->provider_name = strdup(provider_name); proxy_context->provider_publickey_s = strdup(provider_publickey_s); proxy_context->resolver_ip = strdup(resolver_ip); if (proxy_context->provider_name == NULL || proxy_context->provider_publickey_s == NULL || proxy_context->resolver_ip == NULL) { logger_noformat(proxy_context, LOG_EMERG, "Out of memory"); exit(1); } return 1; }
/* Implements a DNS server for the connect_hostname test and the * getaddrinfo_async test */ static void be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data) { int i; int *n_got_p=data; int added_any=0; ++*n_got_p; for (i=0;i<req->nquestions;++i) { const int qtype = req->questions[i]->type; const int qclass = req->questions[i]->dns_question_class; const char *qname = req->questions[i]->name; struct in_addr ans; struct in6_addr ans6; memset(&ans6, 0, sizeof(ans6)); if (qtype == EVDNS_TYPE_A && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) { ans.s_addr = htonl(0x7f000001); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (!evutil_ascii_strcasecmp(qname, "nosuchplace.example.com")) { /* ok, just say notfound. */ } else if (!evutil_ascii_strcasecmp(qname, "both.example.com")) { if (qtype == EVDNS_TYPE_A) { ans.s_addr = htonl(0x50502020); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (qtype == EVDNS_TYPE_AAAA) { ans6.s6_addr[0] = 0x80; ans6.s6_addr[1] = 0xff; ans6.s6_addr[14] = 0xbb; ans6.s6_addr[15] = 0xbb; evdns_server_request_add_aaaa_reply(req, qname, 1, &ans6.s6_addr, 2000); added_any = 1; } evdns_server_request_add_cname_reply(req, qname, "both-canonical.example.com", 1000); } else if (!evutil_ascii_strcasecmp(qname, "v4only.example.com") || !evutil_ascii_strcasecmp(qname, "v4assert.example.com")) { if (qtype == EVDNS_TYPE_A) { ans.s_addr = htonl(0x12345678); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (!evutil_ascii_strcasecmp(qname, "v4assert.example.com")) { TT_FAIL(("Got an AAAA request for v4assert")); } } else if (!evutil_ascii_strcasecmp(qname, "v6only.example.com") || !evutil_ascii_strcasecmp(qname, "v6assert.example.com")) { if (qtype == EVDNS_TYPE_AAAA) { ans6.s6_addr[0] = 0x0b; ans6.s6_addr[1] = 0x0b; ans6.s6_addr[14] = 0xf0; ans6.s6_addr[15] = 0x0d; evdns_server_request_add_aaaa_reply(req, qname, 1, &ans6.s6_addr, 2000); added_any = 1; } else if (!evutil_ascii_strcasecmp(qname, "v6assert.example.com")) { TT_FAIL(("Got a A request for v6assert")); } } else if (!evutil_ascii_strcasecmp(qname, "v6timeout.example.com")) { if (qtype == EVDNS_TYPE_A) { ans.s_addr = htonl(0xabcdef01); evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 2000); added_any = 1; } else if (qtype == EVDNS_TYPE_AAAA) { /* Let the v6 request time out.*/ evdns_server_request_drop(req); return; } } else if (!evutil_ascii_strcasecmp(qname, "v4timeout.example.com")) { if (qtype == EVDNS_TYPE_AAAA) { ans6.s6_addr[0] = 0x0a; ans6.s6_addr[1] = 0x0a; ans6.s6_addr[14] = 0xff; ans6.s6_addr[15] = 0x01; evdns_server_request_add_aaaa_reply(req, qname, 1, &ans6.s6_addr, 2000); added_any = 1; } else if (qtype == EVDNS_TYPE_A) { /* Let the v4 request time out.*/ evdns_server_request_drop(req); return; } } else if (!evutil_ascii_strcasecmp(qname, "v6timeout-nonexist.example.com")) { if (qtype == EVDNS_TYPE_A) { /* Fall through, give an nexist. */ } else if (qtype == EVDNS_TYPE_AAAA) { /* Let the v6 request time out.*/ evdns_server_request_drop(req); return; } } else if (!evutil_ascii_strcasecmp(qname, "all-timeout.example.com")) { /* drop all requests */ evdns_server_request_drop(req); return; } else { TT_GRIPE(("Got weird request for %s",qname)); } } if (added_any) evdns_server_request_respond(req, 0); else evdns_server_request_respond(req, 3); }
static void dns_server_request_cb(struct evdns_server_request *req, void *data) { int i, r; const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa"; const char TEST_IN6[] = "f.e.f.e." "0.0.0.0." "0.0.0.0." "1.1.1.1." "a.a.a.a." "0.0.0.0." "0.0.0.0." "0.f.f.f.ip6.arpa"; for (i = 0; i < req->nquestions; ++i) { const int qtype = req->questions[i]->type; const int qclass = req->questions[i]->dns_question_class; const char *qname = req->questions[i]->name; struct in_addr ans; ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ if (qtype == EVDNS_TYPE_A && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, "zz.example.com")) { r = evdns_server_request_add_a_reply(req, qname, 1, &ans.s_addr, 12345); if (r<0) dns_ok = 0; } else if (qtype == EVDNS_TYPE_AAAA && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, "zz.example.com")) { char addr6[17] = "abcdefghijklmnop"; r = evdns_server_request_add_aaaa_reply(req, qname, 1, addr6, 123); if (r<0) dns_ok = 0; } else if (qtype == EVDNS_TYPE_PTR && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, TEST_ARPA)) { r = evdns_server_request_add_ptr_reply(req, NULL, qname, "ZZ.EXAMPLE.COM", 54321); if (r<0) dns_ok = 0; } else if (qtype == EVDNS_TYPE_PTR && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, TEST_IN6)){ r = evdns_server_request_add_ptr_reply(req, NULL, qname, "ZZ-INET6.EXAMPLE.COM", 54322); if (r<0) dns_ok = 0; } else if (qtype == EVDNS_TYPE_A && qclass == EVDNS_CLASS_INET && !evutil_ascii_strcasecmp(qname, "drop.example.com")) { if (evdns_server_request_drop(req)<0) dns_ok = 0; return; } else { printf("Unexpected question %d %d \"%s\" ", qtype, qclass, qname); dns_ok = 0; } } r = evdns_server_request_respond(req, 0); if (r<0) { printf("Couldn't send reply. "); dns_ok = 0; } }