示例#1
0
/* 
 * -- 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;
}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
0
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;
}