lxl_dns_rrset_t * lxl_dns_rrset_soafind(lxl_list_t *head) { lxl_list_t *list; lxl_dns_rrset_t *rrset; for (list = lxl_list_next(head); list != lxl_list_sentinel(head); list = lxl_list_next(list)) { rrset = lxl_list_data(list, lxl_dns_rrset_t, list); if (rrset->type == LXL_DNS_SOA) { if (rrset->expires_sec > lxl_current_sec) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns soafind rrset"); #endif return rrset; } #if LXL_DEBUG else { lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns soafind expires %lds", lxl_current_sec - rrset->expires_sec); } #endif } } #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns not soafind rrset"); #endif return NULL; }
lxl_dns_rrset_t * lxl_dns_rrset_dnsfind(lxl_list_t *head, char *name, uint16_t nlen, uint16_t type) { lxl_list_t *list; lxl_dns_rrset_t *rrset; for (list = lxl_list_next(head); list != lxl_list_sentinel(head); list = lxl_list_next(list)) { rrset = lxl_list_data(list, lxl_dns_rrset_t, list); if (rrset->nlen == nlen && (rrset->type == type || (rrset->type == LXL_DNS_CNAME && (rrset->soa_flags & LXL_DNS_RRSET_NORMAL_TYPE))) && memcmp(rrset->name, name, nlen) == 0) { if (rrset->expires_sec > lxl_current_sec) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns dnsfind rrset: name:%s nlen:%hu type:%04x", name, nlen, type); #endif return rrset; } #if DEBUG else { lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns find expires %lds rrset: name:%s nlen:%hu type:%04x", lxl_current_sec - rrset->expires_sec, name, nlen, type); } #endif } } #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns not dnsfind rrset: name:%s nlen:%hu type:0x%04x", name, nlen, type); #endif return NULL; }
lxl_int_t lxl_event_connect_peer_udp(lxl_connection_t **c) { int fd; lxl_connection_t *connection; lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "event udp connect peer"); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { lxl_log_error(LXL_LOG_ERROR, errno, "socket() failed"); return -1; } lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "socket %d", fd); connection = lxl_get_connection(fd); if (connection == NULL) { lxl_log_error(LXL_LOG_WARN, 0, "get connection() failed"); close(fd); return -1; } // nonblock connection->udp = 1; connection->closefd = 1; connection->fd = fd; //connection->sockaddr = *sa; //connection->socklen = len; connection->recv = lxl_recvfrom; connection->send = lxl_sendto; *c = connection; return 0; }
void lxl_dns_zone_update(lxl_dns_zone_t *zone) { lxl_list_t *list1, *list2; lxl_dns_rrset_t *rrset; lxl_dns_rdata_t *rdata; lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns zone update"); zone->update_sec = lxl_current_sec; for (list1 = lxl_list_head(&zone->rrset_list); list1 != lxl_list_sentinel(&zone->rrset_list); list1 = lxl_list_next(list1)) { rrset = lxl_list_data(list1, lxl_dns_rrset_t, list); if (rrset->update_flags) { rrset->update_flags = 0; for (list2 = lxl_list_head(&rrset->rdata_list); list2 != lxl_list_sentinel(&rrset->rdata_list); list2 = lxl_list_next(list2)) { rdata = lxl_list_data(list2, lxl_dns_rdata_t, list); if (rdata->update_flags) { rdata->update_flags = 0; } else { lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "delete rrset: name:%s nlen:%hu type:0x%04x rdata:%s rdlength:%hu", rrset->name, rrset->nlen, rrset->type, rdata->rdata, rdata->rdlength); lxl_list_del(list2); //lxl_free(rdata); } } } } }
lxl_dns_rdata_t * lxl_dns_rdata_typefind(lxl_list_t *head, char *rdata, uint16_t rdlength, uint16_t type) { lxl_list_t *list; lxl_dns_rdata_t *dns_rdata; for (list = lxl_list_next(head); list != lxl_list_sentinel(head); list = lxl_list_next(list)) { dns_rdata = lxl_list_data(list, lxl_dns_rdata_t, list); if (dns_rdata->rdlength == rdlength) { if (type == LXL_DNS_MX) { if (memcmp(dns_rdata->rdata + 2, rdata + 2, rdlength - 2) == 0) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns find: rdata:%s rdlength:%hu type:MX", rdata + 2, rdlength); #endif return dns_rdata; } } else { if (memcmp(dns_rdata->rdata, rdata, rdlength) == 0) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns find: rdata:%s rdlength:%hu type:%04x", rdata, rdlength, type); #endif return dns_rdata; } } } } #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns not find: rrdata rdlength:%hu type:%04x", rdlength, type); #endif return NULL; }
lxl_dns_rrset_t * lxl_dns_rrset_typefind(lxl_list_t *head, uint16_t type) { lxl_list_t *list; lxl_dns_rrset_t *rrset; for (list = lxl_list_next(head); list != lxl_list_sentinel(head); list = lxl_list_next(list)) { rrset = lxl_list_data(list, lxl_dns_rrset_t, list); if (rrset->type == type && (rrset->soa_flags & LXL_DNS_RRSET_NORMAL_TYPE)) { if (rrset->expires_sec > lxl_current_sec) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns typefind rrset type:%04x", type); #endif return rrset; } #if LXL_DEBUG else { lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns find expires %lds rrset: type:%04x", lxl_current_sec - rrset->expires_sec, type); } #endif } } #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns not typefind rrset:%04x", type); #endif return NULL; }
static void lxl_dfss_writer(lxl_dfss_request_t *r) { int rc; ssize_t n; lxl_buf_t *b; lxl_event_t *wev; lxl_connection_t *c; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss writer handler"); c = r->connection; wev = c->write; b = r->out; if (wev->timedout) { // delayed lxl_log_error(LXL_LOG_INFO, 0, "client timed out"); c->timedout = 1; lxl_dfss_finalize_request(r, LXL_DFS_REQUEST_TIMEOUT); return; } n = c->send(c, b->pos, b->last - b->pos); if (n == LXL_ERROR) { c->error = 1; lxl_dfss_close_request(r, 0); return; } if (n == LXL_EAGAIN) { goto done; } b->pos += n; if (b->pos < b->last) { goto done; } lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss writer done"); lxl_dfss_finalize_request(r, LXL_OK); return; done: if (!wev->timer_set) { lxl_add_timer(wev, 6 * 1000); } if (lxl_handle_write_event(wev, 0) != 0) { lxl_dfss_close_request(r, 0); } return; }
static void lxl_dfss_process_request_header(lxl_event_t *rev) { //int rc; size_t nread; ssize_t n; lxl_buf_t *b; lxl_connection_t *c; lxl_dfss_request_t *r; c = rev->data; r = c->data; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss process request header"); if (rev->timedout) { lxl_log_error(LXL_LOG_ERROR, 0, "client timed out"); c->timedout = 1; lxl_dfss_close_request(r, LXL_DFS_REQUEST_TIMEOUT); return; } b = r->header_buf; nread = b->last - b->pos; //lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss read byte:%lu", b->last - b->pos); if (nread < sizeof(lxl_dfs_request_header_t)) { n = lxl_dfss_read_request_header(r); if (n == LXL_EAGAIN || n == LXL_ERROR) { return; } nread = b->last - b->pos; } lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss read byte:%lu", nread); if (nread >= sizeof(lxl_dfs_request_header_t)) { if (lxl_dfss_parse_request(r, b->pos) == -1) { lxl_dfss_finalize_request(r, r->response_header.rcode); return; } lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss process request: %s, %u, %hu, 0x%04x", r->rid, r->request_header.body_n, r->request_header.flen, r->request_header.qtype); // b->pos = b->start; // b->last = b->start; //b->last = b->pos; b->pos += 8; lxl_dfss_process_request(r); } }
void lxl_time_update() { struct timeval tv; #if 0 lxl_log_debug(LXL_LOG_DEBUG_CORE, 0, "time update old:%lu %lu", lxl_current_sec, lxl_current_msec); #endif //lxl_cache_sec = lxl_current_sec; gettimeofday(&tv, NULL); lxl_current_sec = tv.tv_sec; lxl_current_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000; #if 0 lxl_log_debug(LXL_LOG_DEBUG_CORE, 0, "time update new:%lu %lu", lxl_current_sec, lxl_current_msec); #endif }
char * lxl_errlog_module_init_conf(lxl_cycle_t *cycle, void *conf) { lxl_log_conf_t *lcf = (lxl_log_conf_t *) conf; int fd; fd = cycle->log->fd; if (!lcf->use_stderr) { lxl_log_debug(LXL_LOG_DEBUG_CORE, 0, "open log file: %s", lcf->file.data); cycle->log->fd = open(lcf->file.data, O_CREAT|O_WRONLY|O_APPEND, 0666); if (cycle->log->fd == -1) { lxl_log_error(LXL_LOG_EMERG, errno, "open(%s) failed", lcf->file.data); return LXL_CONF_ERROR; } } else { cycle->log->fd = STDERR_FILENO; } if (close(fd) == -1) { lxl_log_error(LXL_LOG_ALERT, errno, "close() build-in log failed"); } cycle->log->use_flush = lcf->use_flush; cycle->log->use_stderr = lcf->use_stderr; cycle->log->error_level = lcf->error_level; cycle->log->debug_level = lcf->debug_level; memcpy(cycle->log->file, lcf->file.data, lcf->file.len + 1); return LXL_CONF_OK; }
lxl_int_t lxl_event_connect_peer(lxl_connection_t **c, struct sockaddr *sa, socklen_t len) { lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "event connect peer"); return 0; }
static void lxl_dfst_storage_send_request(lxl_dfst_request_t *r, lxl_dfst_upstream_t *u) { int rc; lxl_connection_t *c; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfst storage send request"); c = u->peer.connection; if (rc == LXL_EAGAIN) { if (lxl_handle_write_event(c->write, 0) != 0) { return; } return; } lxl_add_timer(c->read, 3000); if (c->read->ready) { lxl_dfst_storage_process_header(r, u); } if (lxl_handle_write_event(c->write, 0) != 0) { // finalize return; } }
void lxl_dfss_block_reading(lxl_dfss_request_t *r) { lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss request reading blocked %s", r->rid); return; }
void lxl_dfss_request_empty_handler(lxl_dfss_request_t *r) { lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss request empty handler"); return; }
static void lxl_dfst_storage_dummy_handler(lxl_dfst_request_t *r, lxl_dfst_upstream_t *u) { lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfst storage dummy handler"); return; }
static void lxl_dfss_empty_handler(lxl_event_t *ev) { lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss empty handler"); return; }
void lxl_dfss_report_state_handler(lxl_event_t *ev) { lxl_connection_t *c; lxl_dfss_port_t *port; lxl_dfss_request_t *r; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss report state handler"); lxl_dfss_update_system_state(); c = ev->data; port = c->listening->servers; c->data = r = lxl_dfss_create_request(c); if (r == NULL) { /* not dfss colse connection */ return; } r->main_conf = port->addr.ctx->main_conf; r->srv_conf = port->addr.ctx->srv_conf; r->request_header.qtype = LXL_DFS_STORAGE_REPORT_STATE; r->handler = lxl_dfss_report_state_done_handle_request; lxl_dfss_tracker_init(r); }
static void lxl_worker_process_cycle(lxl_cycle_t *cycle, lxl_int_t worker) { lxl_worker_process_init(cycle, worker); for (; ;) { lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "worker cycle"); lxl_process_events_and_timers(cycle); } }
static void lxl_dfss_report_state_done_handle_request(lxl_dfss_request_t *r) { lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss report stat done"); lxl_add_timer(&lxl_dfss_report_state_event, 300*1000); //lxl_dfss_finalize_request(r, LXL_OK); lxl_dfss_free_request(r, LXL_OK); }
static int lxl_dfss_send_special_response(lxl_dfss_request_t *r, lxl_int_t rc) { lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss send special response: %ld", rc); r->response_header.rcode = rc; lxl_dfss_send_header(r); return LXL_OK; }
static void lxl_dfss_process_request(lxl_dfss_request_t *r) { lxl_int_t rc; lxl_connection_t *c; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss process request"); c = r->connection; if (c->read->timer_set) { lxl_del_timer(c->read); } c->read->handler = lxl_dfss_request_handler; c->write->handler = lxl_dfss_request_handler; r->read_event_handler = lxl_dfss_block_reading; //r->read_event_handler = block_reading switch (r->request_header.qtype) { case LXL_DFS_UPLOAD: r->handler = lxl_dfss_upload_done_handle_request; rc = lxl_dfss_read_client_request_body(r, lxl_dfss_tracker_init); break; case LXL_DFS_UPLOAD_SC: r->handler = lxl_dfss_upload_sc_sync_handle_request; rc = lxl_dfss_read_client_request_body(r, lxl_dfss_tracker_init); break; case LXL_DFS_STORAGE_SYNC_PUSH: rc = lxl_dfss_read_client_request_body(r, lxl_dfss_sync_push_done_handle_request); break; case LXL_DFS_DOWNLOAD: rc = lxl_dfss_read_client_request_body(r, lxl_dfss_download_handle_request); break; case LXL_DFS_DELETE: rc = LXL_DFS_NOT_IMPLEMENTED; break; default: lxl_log_error(LXL_LOG_ERROR, 0, "dfss Unknow request qtype: %04X", r->request_header.qtype); break; } if (rc > LXL_DFS_OK) { lxl_dfss_finalize_request(r, rc); } }
lxl_dns_rdata_t * lxl_dns_rdata_find(lxl_list_t *head, char *rdata, uint16_t rdlength) { lxl_list_t *list; lxl_dns_rdata_t *dns_rdata; for (list = lxl_list_next(head); list != lxl_list_sentinel(head); list = lxl_list_next(list)) { dns_rdata = lxl_list_data(list, lxl_dns_rdata_t, list); if (dns_rdata->rdlength == rdlength && memcmp(dns_rdata->rdata, rdata, rdlength) == 0) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns typefind rdata %s, rdlength %hu", rdata, rdlength); #endif return dns_rdata; } } #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns not typefind rrdata %s, rdlength %hu", rdata, rdlength); #endif return NULL; }
static void lxl_dfss_upload_sc_sync_handle_request(lxl_dfss_request_t *r) { lxl_str_t *fid; lxl_file_t *file; fid = &r->body->fid; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss upload sc sync push %s", fid->data); r->handler = lxl_dfss_upload_sc_sync_done_handle_request; lxl_dfss_storage_init(r); }
lxl_dns_rdata_t * lxl_dns_rdata_create(char *data, size_t len, uint16_t type) { lxl_dns_rdata_t *rdata; // switch mx soa if (type == LXL_DNS_A) { /* uint32_t */ rdata = lxl_alloc(sizeof(lxl_dns_rdata_t) + 4); if (rdata == NULL) { return NULL; } if (inet_pton(AF_INET, data, (void *) &rdata->rdata) <= 0) { goto failed; } rdata->rdlength = 4; } else if (type == LXL_DNS_AAAA) { /* 8 * uint16_t */ rdata = lxl_alloc(sizeof(lxl_dns_rdata_t) + 16); if (rdata == NULL) { return NULL; } if (inet_pton(AF_INET6, data, (void *) &rdata->rdata) <= 0) { goto failed; } rdata->rdlength = 16; // } else { } else if (type == LXL_DNS_NS) { lxl_dns_domain_dot_to_label(data, len); rdata = lxl_alloc(sizeof(lxl_dns_rdata_t) + len + 1); if (rdata == NULL) { return NULL; } memcpy(&rdata->rdata, data, len + 1); rdata->rdlength = (uint16_t) len + 1; } else { return NULL; } return rdata; failed: //lxl_free(rdata); lxl_log_debug(LXL_LOG_ERROR, errno, "inet_pton(type:%04x) failed", type); return NULL; }
static void lxl_dfss_close_connection(lxl_connection_t *c) { lxl_pool_t *pool; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss close connection"); pool = c->pool; lxl_close_connection(c); /* timer event */ if (pool) { /* udp */ lxl_destroy_pool(pool); } }
static void lxl_dfss_upload_sync_done_handle_request(lxl_dfss_request_t *r) { size_t n; lxl_str_t *fid; lxl_buf_t *b; lxl_connection_t *c; fid = &r->body->fid; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss upload sync push done %s", fid->data); lxl_dfss_finalize_request(r, LXL_OK); }
lxl_dns_rrset_t * lxl_dns_rrset_find(lxl_list_t *head, char *name, uint16_t nlen, uint16_t type, uint16_t flags) { lxl_list_t *l; lxl_dns_rrset_t *rrset; for (l = lxl_list_next(head); l != lxl_list_sentinel(head); l = lxl_list_next(l)) { rrset = lxl_list_data(l, lxl_dns_rrset_t, list); if (rrset->nlen == nlen && (rrset->type == type) && memcmp(rrset->name, name, nlen) == 0) { if (flags) { if (rrset->expires_sec > lxl_current_sec) { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns expires find rrset: name:%s nlen:%hu type:%04x", name, nlen, type); #endif return rrset; } #if LXL_DEBUG else { lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns expires find expires %lds rrset: name:%s nlen:%hu type:%04x", lxl_current_sec - rrset->expires_sec, name, nlen, type); } #endif } else { #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns normal find rrset: name:%s nlen:%hu type:%04x", name, nlen, type); #endif return rrset; } } } #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_DNS, 0, "dns not find rrset: name:%s nlen:%hu type:%04x", name, nlen, type); #endif return NULL; }
void lxl_process_events_and_timers(lxl_cycle_t *cycle) { lxl_uint_t timer, delta; #if LXL_DEBUG lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "process events and timer"); #endif timer = lxl_event_find_timer(); if (lxl_use_accept_mutex) { if (lxl_accept_disabled > 0) { lxl_accept_disabled = cycle->connection_n / 8 - cycle->free_connection_n; if (lxl_accept_disabled <= 0) { lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "enable accept events"); lxl_enable_accept_events(cycle); } } else { lxl_accept_disabled = cycle->connection_n / 8 - cycle->free_connection_n; if (lxl_accept_disabled > 0) { lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "disable accept events"); lxl_disable_accept_events(cycle); } } } delta = lxl_current_msec; lxl_process_events(timer); delta = lxl_current_msec - delta; lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "timer delta: %lu", delta); if (delta) { /* timer not exact */ lxl_event_expire_timers(); } }
static void lxl_dfss_upload_sc_sync_done_handle_request(lxl_dfss_request_t *r) { size_t n; lxl_str_t *fid; lxl_buf_t *b; lxl_connection_t *c; fid = &r->body->fid; lxl_log_debug(LXL_LOG_DEBUG_DFS, 0, "dfss upload sc sync push done %s", fid->data); c = r->connection; b = r->out = r->header_buf; lxl_reset_buf(b); r->response_header.body_n = fid->len; *((uint32_t *) b->last) = htonl(r->response_header.body_n); b->last += 4; *((uint16_t *) b->last) = htons(r->response_header.flen); b->last += 2; *((uint16_t *) b->last) = htons(r->response_header.rcode); b->last += 2; memcpy(b->last, fid->data, fid->len); b->last += fid->len; n = c->send(c, b->pos, b->last - b->pos); if (n == -1) { lxl_dfss_finalize_request(r, LXL_DFS_SERVER_ERROR); return; } b->pos += n; if (b->pos < b->last) { c->read->handler = lxl_dfss_request_handler; c->write->handler = lxl_dfss_request_handler; r->read_event_handler = lxl_dfss_request_empty_handler; r->write_event_handler = lxl_dfss_writer; lxl_add_timer(c->write, 10 * 1000); if (lxl_handle_write_event(c->write, 0) != 0) { lxl_dfss_finalize_request(r, LXL_DFS_SERVER_ERROR); return; } } lxl_dfss_finalize_request(r, LXL_OK); }
static void lxl_close_accepted_connection(lxl_connection_t *c, lxl_uint_t flags) { lxl_log_debug(LXL_LOG_DEBUG_EVENT, 0, "close accepted connection socket %d", c->fd); lxl_free_connection(c); if (flags == LXL_CONNECTION_CLOSE_SOCKET) { if (close(c->fd) == -1) { lxl_log_error(LXL_LOG_ALERT, errno, "close socket %d failed", c->fd); } } c->fd = -1; if (c->pool) { lxl_destroy_pool(c->pool); } }