/* * -- qryrecv * * receives a query from a TCP connection making sure that * the message is complete. * The query is formatted as an HTTP request so it must end with * an empty line. * */ qreq_t * qryrecv(int sd, timestamp_t now) { char buf[8*1024]; /* XXX large but arbitrary */ int rd; size_t ofs; /* * Read as much as possible from the socket. * The message must end with a pair of \n. */ ofs = 0; bzero(buf, sizeof(buf)); for (;;) { /* leave last byte unused, so we are sure to find a \0 there. */ rd = read(sd, buf + ofs, sizeof(buf) - ofs - 1); logmsg(V_LOGQUERY, "qryrecv read returns %d\n", rd); if (rd < 0) /* other end closed connection ? */ return NULL; ofs += rd; if (strstr(buf, "\n\n") != NULL || strstr(buf, "\n\r\n") != NULL) /* found terminator */ return query_parse(buf, now); if (rd == 0 || buf[0] < ' ') /* invalid string */ break; } return NULL; }
static char *read_query(const char *basepath, const char *filename, char *buff, char **end, query_t *q) { char path[FILENAME_MAX]; snprintf(path, FILENAME_MAX, "%s%s", basepath, filename); { file_map_t map; if (!file_map_open(&map, path, false)) { UNIXERR("open"); return NULL; } if (map.end - map.map >= BUFSIZ) { err("File too large for a testcase: %s", path); file_map_close(&map); return NULL; } memcpy(buff, map.map, map.end - map.map); if (end != NULL) { *end = buff + (map.end - map.map); **end = '\0'; } else { buff[map.end - map.map] = '\0'; } file_map_close(&map); } char *eoq = strstr(buff, "\n\n"); if (eoq == NULL) { return NULL; } if (!query_parse(q, buff)) { err("Cannot parse query from file %s", filename); return NULL; } return eoq + 2; }
static void * dispatcher_thread_handler( void * args) { int index = *((int *) args); free(args); int listenfd; struct sockaddr_in client_addr, server_addr; socklen_t addrLen; char query_buffer[NS_MAXMSG]; int queryLen; int port_num = PORT_DISPATCHER + index; listenfd = CreateServerSocket(AF_INET, SOCK_DGRAM, "127.0.0.1", PORT_DISPATCHER + index, (struct sockaddr *)&server_addr); if( listenfd <0) { my_log("Error: Cannot create server socket for dispatcher %d, port :%d \n", index, port_num); disp_addr[index].sockfd= -1; disp_addr[index].port= -1; pthread_exit(NULL); } disp_addr[index].port= port_num; //Tell the recv_send thread where I am ready disp_addr[index].ready= TRUE; debug("Dispatcher[%d] is ready\n", index); fd_set read_fds; int max = listenfd +1; int num, rcode; for (;;) { if (parentRequestStop) { //debug("dispacher[%d] will quit now on request.\n", index); break; } //debug("Dispatcher[%d] is working...\n", index); while(parentRequestPause){}; FD_ZERO(&read_fds); FD_SET(listenfd, &read_fds); struct timeval timeout={TIMEOUT,0}; int count = select(max, &read_fds, NULL, NULL, &timeout); if (count < 0) //Maybe Interrupted, such as ^C pressed { //break; continue; } if(count == 0) //No event in timeout { continue; } if (FD_ISSET(listenfd, &read_fds) ) { memset(query_buffer, 0, sizeof(query_buffer)); addrLen=sizeof(client_addr); //queryLen = recvfrom(listenfd, (char *) &num , NS_MAXMSG, 0, queryLen = recvfrom(listenfd, (char *) &num , sizeof(num), 0, (struct sockaddr * )&client_addr, &addrLen); if( queryLen < 2 || num <0 || num >= MAX_QUERY_NUM) { //my_log("Error: read index of query error, len=%d, num=%d\n", // queryLen, num); continue; } Query *pQuery = queries.queries[num]; //querylist_lookup_byIndex(&queries,num); if (pQuery == NULL) { //my_log("Error: Cannot find query[%d]\n", num); continue; } rcode = query_parse(pQuery); if ( rcode == -1) { //my_log("Error: Can't parse query in dispatch\n"); //it should be freed here querylist_free_item(&queries, num); continue; } long cAddr_h; struct sockaddr_in *pca; pca = &pQuery->client_addr; cAddr_h = ntohl(pca->sin_addr.s_addr); Action *pAct = policy_lookup(&policy, cAddr_h, pQuery->qname); //resolver_display( pAct->resolver); //char strAddr[MAX_WORD]; if ( pAct == NULL) { /* my_log("Error: No Policy for this query(from %s for name:%s) \n", sock_ntop((SA*) &(pQuery->client_addr), sizeof(SA), strAddr, sizeof(strAddr)), pQuery->qname); */ //query_free(pQuery); //queries.queries[num]=NULL; querylist_free_item(&queries,num); } if( pAct->op == Drop) { /* my_log("Dropped query(from %s for name:%s) \n", sock_ntop((SA*) &(pQuery->client_addr), sizeof(SA), strAddr, sizeof(strAddr)), pQuery->qname); */ //query_free(pQuery); //queries.queries[num]=NULL; querylist_free_item(&queries,num); } else if ( pAct->op == Forward || pAct->op == Refuse || pAct->op == Redirect ) { pQuery->status = dispatched; pQuery->resolver = pAct->resolver; pQuery->op = pAct->op; //notify the recv_send that this query is ready for forwarding sendto( listenfd, (char *) &num, sizeof(num), 0, (SA*)&client_addr, addrLen); //debug("Policy lookup finished for %d: %s \n", num, pQuery->qname ); } } //IF(ISSET() } //for(;;) debug("Dispatcher thread[%d] will exit...\n", index); pthread_exit(NULL); }
int handle_domain_records(struct evhttp_request * const req, HttpHandlerContext * const context, char *uri, char *opts, _Bool * const write_to_log, const _Bool fake_req) { Key *layer_name; Key *key; (void) opts; if (req->type == EVHTTP_REQ_GET) { Op op; RecordsGetOp * const get_op = &op.records_get_op; char *sep; if ((sep = strchr(uri, '/')) == NULL) { return HTTP_NOTFOUND; } *sep = 0; if ((layer_name = new_key_from_c_string(uri)) == NULL) { *sep = '/'; return HTTP_SERVUNAVAIL; } *sep++ = '/'; if (*sep == 0) { release_key(layer_name); return HTTP_NOTFOUND; } if ((key = new_key_from_c_string(sep)) == NULL) { release_key(layer_name); return HTTP_SERVUNAVAIL; } RecordsOptParseCBContext cb_context = { .with_links = 0 }; if (opts != NULL && query_parse(opts, records_opt_parse_cb, &cb_context) != 0) { release_key(layer_name); return HTTP_BADREQUEST; } *get_op = (RecordsGetOp) { .type = OP_TYPE_RECORDS_GET, .req = req, .fake_req = fake_req, .op_tid = ++context->op_tid, .layer_name = layer_name, .key = key, .with_links = cb_context.with_links }; pthread_mutex_lock(&context->mtx_cqueue); if (push_cqueue(context->cqueue, get_op) != 0) { pthread_mutex_unlock(&context->mtx_cqueue); release_key(layer_name); release_key(key); return HTTP_SERVUNAVAIL; } pthread_mutex_unlock(&context->mtx_cqueue); pthread_cond_signal(&context->cond_cqueue); return 0; } if (req->type == EVHTTP_REQ_PUT) { Op op; RecordsPutOp * const put_op = &op.records_put_op; char *sep; if ((sep = strchr(uri, '/')) == NULL) { return HTTP_NOTFOUND; } *sep = 0; if ((layer_name = new_key_from_c_string(uri)) == NULL) { return HTTP_SERVUNAVAIL; } *sep++ = '/'; if (*sep == 0) { release_key(layer_name); return HTTP_NOTFOUND; } if ((key = new_key_from_c_string(sep)) == NULL) { release_key(layer_name); return HTTP_SERVUNAVAIL; } evbuffer_add(evhttp_request_get_input_buffer(req), "", (size_t) 1U); const char *body = (char *) evbuffer_pullup(evhttp_request_get_input_buffer(req), -1); *put_op = (RecordsPutOp) { .type = OP_TYPE_RECORDS_PUT, .req = req, .fake_req = fake_req, .op_tid = ++context->op_tid, .layer_name = layer_name, .key = key, .position = { .latitude = (Dimension) -1, .longitude = (Dimension) -1 }, .position_set = 0, .properties = NULL, .special_properties = NULL, .expires_at = (time_t) 0 }; RecordsPutOptParseCBContext cb_context = { .put_op = put_op }; if (query_parse(body, records_put_opt_parse_cb, &cb_context) != 0) { free_slip_map(&put_op->properties); free_slip_map(&put_op->special_properties); release_key(layer_name); release_key(key); return HTTP_BADREQUEST; } pthread_mutex_lock(&context->mtx_cqueue); if (push_cqueue(context->cqueue, put_op) != 0) { pthread_mutex_unlock(&context->mtx_cqueue); free_slip_map(&put_op->properties); free_slip_map(&put_op->special_properties); release_key(layer_name); release_key(key); return HTTP_SERVUNAVAIL; } pthread_mutex_unlock(&context->mtx_cqueue); pthread_cond_signal(&context->cond_cqueue); *write_to_log = 1; return 0; } if (req->type == EVHTTP_REQ_DELETE) { Op op; RecordsDeleteOp * const delete_op = &op.records_delete_op; char *sep; if ((sep = strchr(uri, '/')) == NULL) { return HTTP_NOTFOUND; } *sep = 0; if ((layer_name = new_key_from_c_string(uri)) == NULL) { return HTTP_SERVUNAVAIL; } *sep++ = '/'; if (*sep == 0) { release_key(layer_name); return HTTP_NOTFOUND; } if ((key = new_key_from_c_string(sep)) == NULL) { release_key(layer_name); return HTTP_SERVUNAVAIL; } *delete_op = (RecordsDeleteOp) { .type = OP_TYPE_RECORDS_DELETE, .req = req, .fake_req = fake_req, .op_tid = ++context->op_tid, .layer_name = layer_name, .key = key }; pthread_mutex_lock(&context->mtx_cqueue); if (push_cqueue(context->cqueue, delete_op) != 0) { pthread_mutex_unlock(&context->mtx_cqueue); release_key(layer_name); release_key(key); return HTTP_SERVUNAVAIL; } pthread_mutex_unlock(&context->mtx_cqueue); pthread_cond_signal(&context->cond_cqueue); *write_to_log = 1; return 0; } return HTTP_NOTFOUND; }