Пример #1
0
int send_http_request(int sockfd,const char *hostname,ushort port,const char *filename)
{
	struct http_request_header *request;
	int ret;

	request = create_http_header();

	init_get_request(request,filename);

	add_host_header(request,hostname,port);
	add_request(request,"Accept: ","*/*");
	add_request(request,"Connection: ","Close");

	end_request(request);

	ret = socket_sendnbuf(sockfd,request->request_buf,request->offset);
	if(ret < 0){
		close(sockfd);
		release_http_header(request);
		return -1;
	}

	release_http_header(request);

	return 0;
}
Пример #2
0
static L4_CV
int b_open(l4fdx_srv_obj srv_obj, unsigned client_req_id,
           const char *path, unsigned len, int flags, unsigned mode)
{
    struct internal_request *r;
    struct l4fdx_client *c = srv_obj->client;

    if (c->filterpath) {
        if (len < c->filterpath_len)
            return -EPERM;

        if (strncmp(c->filterpath, path, c->filterpath_len))
            return -EPERM;
    }

    r = kmalloc(sizeof(struct internal_request), GFP_ATOMIC);
    if (!r)
        return -ENOMEM;

    r->type = L4FS_REQ_OPEN;
    r->client_req_id = client_req_id;
    strlcpy(r->open.path, path, min((size_t)len + 1, sizeof(r->open.path)));
    r->open.flags = flags;
    r->open.mode  = mode;

    add_request(srv_obj, r);

    return 0;
}
Пример #3
0
/* like any C program, program's execution begins in main */
int
main(int argc, char* argv[])
{
    int        i;                                /* loop counter          */
    int        thr_id[NUM_HANDLER_THREADS];      /* thread IDs            */
    pthread_t  p_threads[NUM_HANDLER_THREADS];   /* thread's structures   */
    struct timespec delay;			 /* used for wasting time */

    /* create the request-handling threads */
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
	thr_id[i] = i;
	pthread_create(&p_threads[i], NULL, handle_requests_loop, (void*)&thr_id[i]);
    }

    /* run a loop that generates requests */
    for (i=0; i<600; i++) {
	add_request(i, &request_mutex, &got_request);
	/* pause execution for a little bit, to allow      */
	/* other threads to run and handle some requests.  */
	if (rand() > 3*(RAND_MAX/4)) { /* this is done about 25% of the time */
	    delay.tv_sec = 0;
	    delay.tv_nsec = 10;
	    nanosleep(&delay, NULL);
	}
    }
    /* now wait till there are no more requests to process */
    sleep(5);

    printf("Glory,  we are done.\n");
    
    return 0;
}
Пример #4
0
int main(int argc, char *argv[]) {
    int i;
    int thr_id[NUM_HANDLER_THREADS];
    pthread_t p_threads[NUM_HANDLER_THREADS];
    struct timespec delay;

    /* create the request-handling threads */
    for (i = 0; i < NUM_HANDLER_THREADS; i++) {
        thr_id[i] = i;
        pthread_create(&p_threads[i], NULL, handle_requests_loop,
                       (void *)&thr_id[i]);
    }

    sleep(3);

    /* run a loop that generates requests */
    for (i = 0; i < 600; i++) {
        add_request(i, &request_mutex, &got_request);
        if (rand() > 3 * (RAND_MAX / 4)) {
            delay.tv_sec = 0;
            delay.tv_nsec = 10;
            nanosleep(&delay, NULL);
        }
    }

    sleep(5);
    printf("Glory, we are done.\n");

    return 0;
}
Пример #5
0
/* 主线程 */
int
main(int argc, char* argv[])
{
    int        i;                                /* 循环变量 */
    int        thr_num[NUM_HANDLER_THREADS];      /* 线程序号 */
    pthread_t  p_threads[NUM_HANDLER_THREADS];   /* 线程结构 */
    struct timespec delay;			 /* 延迟时间 */

    /* 创建请求处理线程 */
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
	thr_num[i] = i;
	pthread_create(&p_threads[i], NULL, handle_requests_loop, (void*)&thr_num[i]);
    }

    /* 循环产生请求 */
    for (i=0; i<600; i++) {
	add_request(i, &request_mutex, &got_request);
	/* 暂停一会,以让其它线程运行并处理某些请求 */
	if (rand() > 3*(RAND_MAX/4)) { /* 需要 25% 的时间 */
	    delay.tv_sec = 0;
	    delay.tv_nsec = 10;
	    nanosleep(&delay, NULL);
	}
    }
    /* 等待,直到没有剩下有待处理的请求 */
    sleep(5);

    printf("Glory,  we are done.\n");
    
    return 0;
}
Пример #6
0
void rw_abs_hd(int rw, unsigned int nr, unsigned int sec, unsigned int head,
	       unsigned int cyl, struct buffer_head * bh)
{
    struct hd_request * req;

    if (rw != READ && rw != WRITE)
	panic("Bad hd command, must be R/W");
    lock_buffer(bh);
 repeat:
    for (req = 0 + request; req < NR_REQUEST + request; req++)
	if (req->hd < 0)
	    break;
    if (req == NR_REQUEST + request) {
	sleep_on(&wait_for_request);
	goto repeat;
    }
    req->hd = nr;
    req->nsector = 2;
    req->sector = sec;
    req->head = head;
    req->cyl = cyl;
    req->cmd = ((rw == READ) ? WIN_READ : WIN_WRITE);
    req->bh = bh;
    req->errors = 0;
    req->next = NULL;
    add_request(req);
    wait_on_buffer(bh);
}
static gboolean
grab_request_options (GPtrArray *store, const char* line)
{
	char **areq, **aiter;
	gboolean end = FALSE;

	/* Grab each 'request' or 'also request'  option and save for later */
	areq = g_strsplit_set (line, "\t ,", -1);
	for (aiter = areq; aiter && *aiter; aiter++) {
		if (!strlen (g_strstrip (*aiter)))
			continue;

		if (*aiter[0] == ';') {
			/* all done */
			end = TRUE;
			break;
		}

		if (!g_ascii_isalnum ((*aiter)[0]))
			continue;

		if ((*aiter)[strlen (*aiter) - 1] == ';') {
			/* Remove the EOL marker */
			(*aiter)[strlen (*aiter) - 1] = '\0';
			end = TRUE;
		}

		add_request (store, *aiter);
	}

	if (areq)
		g_strfreev (areq);

	return end;
}
Пример #8
0
void AsyncAcks::expect_ack_from(int from_rank, int tag) {
	MPI_Request request;
	SIPMPIUtils::check_err(
			MPI_Irecv(0, 0, MPI_INT, from_rank, tag, MPI_COMM_WORLD, &request));
	add_request(request);
	cleanup();
}
Пример #9
0
static void make_request(int major,int rw, struct buffer_head * bh)
{
	struct request * req;
	int rw_ahead;

	// 这里指针在 one past the end
	if (rw == READ)
		req = request+NR_REQUEST;

	/// 找到最后一个
	while (--req >= request){
		if (req->dev<0)
			break;
	}
	
	
	/* fill up the request-info, and add it to the queue */
	req->dev = bh->b_dev;
	req->cmd = rw;
	req->errors=0;
	req->sector = bh->b_blocknr<<1;
	req->nr_sectors = 2;
	req->buffer = bh->b_data;
	req->waiting = NULL;
	req->bh = bh;
	req->next = NULL;
	add_request(major+blk_dev,req);
}
Пример #10
0
static void make_request(int major,int rw, struct buffer_head * bh)
{
	//debug("make_request1");
	struct request * req;
	int rw_ahead;

/* WRITEA/READA is special case - it is not really needed, so if the */
/* buffer is locked, we just forget about it, else it's a normal read */
	if (rw_ahead = (rw == READA || rw == WRITEA)) {
		if (bh->b_lock)
			return;
		if (rw == READA)
			rw = READ;
		else
			rw = WRITE;
	}
	if (rw!=READ && rw!=WRITE)
		panic("Bad block dev command, must be R/W/RA/WA");
	lock_buffer(bh);
	//debug("make_request2");
	if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
		unlock_buffer(bh);
		return;
	}
repeat:
/* we don't allow the write-requests to fill up the queue completely:
 * we want some room for reads: they take precedence. The last third
 * of the requests are only for reads.
 */
	if (rw == READ)
		req = request+NR_REQUEST;
	else
		req = request+((NR_REQUEST*2)/3);
/* find an empty request */
	while (--req >= request)
		if (req->dev<0)
			break;
/* if none found, sleep on new requests: check for rw_ahead */
	if (req < request) {
		if (rw_ahead) {
			unlock_buffer(bh);
			return;
		}
		sleep_on(&wait_for_request);
		goto repeat;
	}
/* fill up the request-info, and add it to the queue */
	req->dev = bh->b_dev;
	req->cmd = rw;
	req->errors=0;
	req->sector = bh->b_blocknr<<1;
	req->nr_sectors = 2;
	req->buffer = bh->b_data;
	req->waiting = NULL;
	req->bh = bh;
	req->next = NULL;
	//debug("before add request");
	add_request(major+blk_dev,req);
}
Пример #11
0
static L4_CV
int b_close(l4fdx_srv_obj srv_obj, unsigned client_req_id, int fid)
{
    SETUP_REQUEST(srv_obj->client, client_req_id, fid, L4FS_REQ_CLOSE);
    r->close.fid = fid;

    add_request(srv_obj, r);
    return 0;
}
Пример #12
0
static L4_CV
int b_fstat(l4fdx_srv_obj srv_obj, unsigned client_req_id, int fid,
            unsigned shm_off)
{
    SETUP_REQUEST(srv_obj->client, client_req_id, fid, L4FS_REQ_FSTAT64);
    r->fstat.fid        = fid;
    r->fstat.shm_offset = shm_off;
    add_request(srv_obj, r);
    return 0;
}
Пример #13
0
static L4_CV
int b_write(l4fdx_srv_obj srv_obj, unsigned client_req_id,
            int fid, unsigned long long offset, size_t sz, unsigned shm_off)
{
    SETUP_REQUEST(srv_obj->client, client_req_id, fid, L4FS_REQ_WRITE);
    r->read_write.offset     = offset;
    r->read_write.size       = sz;
    r->read_write.fid        = fid;
    r->read_write.shm_offset = shm_off;

    add_request(srv_obj, r);
    return 0;
}
/* like any C program, program's execution begins in main */
int
main(int argc, char* argv[])
{
    int        i;                                /* loop counter          */
    int        thr_id[NUM_HANDLER_THREADS];      /* thread IDs            */
    pthread_t  p_threads[NUM_HANDLER_THREADS];   /* thread's structures   */
    struct timespec delay;			 /* used for wasting time */

    /* create the request-handling threads */
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
	thr_id[i] = i;
	pthread_create(&p_threads[i], NULL, handle_requests_loop, (void*)&thr_id[i]);
    }

    /* run a loop that generates requests */
    for (i=0; i<600; i++) {
	add_request(i, &request_mutex, &got_request);
	/* pause execution for a little bit, to allow      */
	/* other threads to run and handle some requests.  */
	if (rand() > 3*(RAND_MAX/4)) { /* this is done about 25% of the time */
	    delay.tv_sec = 0;
	    delay.tv_nsec = 1;
	    nanosleep(&delay, NULL);
	}
    }
    /* CHANGE 1 - the main thread modifies the flag     */
    /* to tell its handler threads no new requests will */
    /* be generated.                                    */
    /* notify our threads we're done creating requests. */
    {
        int rc;

        rc = pthread_mutex_lock(&request_mutex);
        done_creating_requests = 1;
        rc = pthread_cond_broadcast(&got_request);
        rc = pthread_mutex_unlock(&request_mutex);
    }

    /* CHANGE 3 - use pthread_join() to wait for all       */
    /* threads to terminate.                               */
    /* now wait till there are no more requests to process */
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
	void* thr_retval;

	pthread_join(p_threads[i], &thr_retval);
    }
    printf("Glory,  we are done.\n");
    
    return 0;
}
static void do_post(const int node, const int tag)
{
  if(_postreq.num == _postreq.max_size){
    XACC_DEBUG("reallocation\n");
    _postreq.max_size *= _XMP_POSTREQ_TABLE_INCREMENT_RATIO;
    size_t next_size = sizeof(_XMP_postreq_info_t) * _postreq.max_size;
    _XMP_postreq_info_t *tmp;
    if((tmp = realloc(_postreq.table, next_size)) == NULL)
      _XMP_fatal("cannot allocate memory");
    else
      _postreq.table = tmp;
  }

  add_request(node, tag);
}
Пример #16
0
void multcher::downloader::handle_result_message(CURLMsg* msg)
{
	multcher_internal_t& p = internal_data[msg->easy_handle];

	_sch.set_finished_ok(p.req.domain);

	if (p.req.is_internal)
	{
		if ((msg->data.result == 0) || (msg->data.result == 22))
		{
			rtxt_consumer.receive(p.req, p.resp, msg->data.result);
		}
		else
		{
			rtxt_consumer.completely_failed(p.req);
		}

		domain_unknown_requests_t durls;
		pthread_mutex_lock(&unknown_urls_mutex);
		unknown_urls[p.req.domain].swap(durls);
		unknown_urls.erase(p.req.domain);
		pthread_mutex_unlock(&unknown_urls_mutex);

		domain_unknown_requests_t::const_iterator it;
		for (it = durls.begin(); it != durls.end(); ++it)
		{
			add_request(*it);
		}
	}
	else
	{
		consumer->receive(p.req, p.resp, msg->data.result);
	}

	if (p.additional_headers) curl_slist_free_all(p.additional_headers);
	internal_data.erase(msg->easy_handle);
	curl_easy_cleanup(msg->easy_handle);
}
Пример #17
0
/*
 * Main server loop
 */
void serve_connections(int sockfd) {

    while(1) {
        // listen on socket
        if(listen(sockfd, BACKLOG) == -1) {
            perror("error listening on socket");
            exit(1);
        }

        // accept incoming connection
        struct sockaddr_in remote_addr;
        socklen_t addr_size = sizeof remote_addr;
        char remote_ip_str[INET6_ADDRSTRLEN];
        int accepted_fd;
        if((accepted_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &addr_size)) == -1) {
            perror("error accepting connection");
            exit(1);
        }

        if(inet_ntop(remote_addr.sin_family, &(remote_addr.sin_addr), remote_ip_str, sizeof remote_ip_str) == NULL) {
            perror("error converting ipaddr to string");
            exit(1);
        }

        printf("Accepted connection from %s\n", remote_ip_str);


        // read from connection
        char recv_buf[BUF_SIZE];
        memset(recv_buf, 0, BUF_SIZE);
        int recv_retval;
        if((recv_retval = recv(accepted_fd, recv_buf, BUF_SIZE, RECV_FLAGS)) == -1) {
            perror("error while recieving from client");
            exit(1);
        } else if(recv_retval == 0) {
            // TODO: probably want to implement some other behavior here
            fprintf(stderr, "client has closed the connection");
            continue;
        }

        /*
         * create the request struct and add the verb, path, and first line
         */
        HTTPreq *http_req = parse_request(recv_buf);

        http_req->ipaddr = strdup(remote_ip_str);
        http_req->connfd = accepted_fd;

        // TODO: check for errors
        http_req->file_stat = get_stat(http_req->path);

        /*
         * content length is the file size if GET, 0 if HEAD.
         */
        http_req->content_len = (http_req->verb == GET) ? http_req->file_stat->st_size : 0;

        // add to the request queue
        add_request(http_req);
    }

}
Пример #18
0
int     main(int argc, char **argv)
{
    DICT_CACHE_TEST *test_job;
    VSTRING *inbuf = vstring_alloc(100);
    char   *bufp;
    ARGV   *args;
    DICT_CACHE *cache = 0;
    int     stdin_is_tty;

    msg_vstream_init(argv[0], VSTREAM_ERR);
    if (argc != 1)
	usage(argv[0]);


    test_job = create_requests(DICT_CACHE_SREQ_LIMIT);

    stdin_is_tty = isatty(0);

    for (;;) {
	if (stdin_is_tty) {
	    vstream_printf("> ");
	    vstream_fflush(VSTREAM_OUT);
	}
	if (vstring_fgets_nonl(inbuf, VSTREAM_IN) == 0)
	    break;
	bufp = vstring_str(inbuf);
	if (!stdin_is_tty) {
	    vstream_printf("> %s\n", bufp);
	    vstream_fflush(VSTREAM_OUT);
	}
	if (*bufp == '#')
	    continue;
	args = argv_split(bufp, DELIMS);
	if (argc == 0) {
	    vstream_printf("usage: %s\n", USAGE);
	    vstream_fflush(VSTREAM_OUT);
	    continue;
	}
	if (strcmp(args->argv[0], "verbose") == 0 && args->argc == 2) {
	    msg_verbose = atoi(args->argv[1]);
	} else if (strcmp(args->argv[0], "elapsed") == 0 && args->argc == 2) {
	    show_elapsed = atoi(args->argv[1]);
#ifdef HAS_LMDB
	} else if (strcmp(args->argv[0], "lmdb_map_size") == 0 && args->argc == 2) {
	    dict_lmdb_map_size = atol(args->argv[1]);
#endif
	} else if (strcmp(args->argv[0], "cache") == 0 && args->argc == 2) {
	    if (cache)
		dict_cache_close(cache);
	    cache = dict_cache_open(args->argv[1], O_CREAT | O_RDWR,
				    DICT_CACHE_OPEN_FLAGS);
	} else if (strcmp(args->argv[0], "reset") == 0 && args->argc == 1) {
	    reset_requests(test_job);
	} else if (strcmp(args->argv[0], "run") == 0 && args->argc == 1) {
	    run_requests(test_job, cache, inbuf);
	} else if (strcmp(args->argv[0], "status") == 0 && args->argc == 1) {
	    show_status(test_job, cache);
	} else {
	    add_request(test_job, args);
	}
	vstream_fflush(VSTREAM_OUT);
	argv_free(args);
    }

    vstring_free(inbuf);
    free_requests(test_job);
    if (cache)
	dict_cache_close(cache);
    return (0);
}
Пример #19
0
/********************************************************************
* FUNCTION mgr_rpc_send_request
*
* Send an <rpc> request to the agent on the specified session
* non-blocking send, reply function will be called when
* one is received or a timeout occurs
*
* INPUTS:
*   scb == session control block
*   req == request to send
*   rpyfn == reply callback function
*
* RETURNS:
*   status
*********************************************************************/
status_t
    mgr_rpc_send_request (ses_cb_t *scb,
                          mgr_rpc_req_t *req,
                          mgr_rpc_cbfn_t rpyfn)
{
    xml_msg_hdr_t msg;
    xml_attr_t   *attr;
    status_t      res;
    boolean       anyout;
    xmlns_id_t    nc_id;

#ifdef DEBUG
    if (!scb || !req || !rpyfn) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

#ifdef MGR_HELLO_DEBUG
    log_debug2("\nmgr sending RPC request %s on session %d", 
               req->msg_id, scb->sid);
#endif

    anyout = FALSE;
    xml_msg_init_hdr(&msg);
    nc_id = xmlns_nc_id();

    /* make sure the message-id attribute is not already present */
    attr = xml_find_attr_q(&req->attrs, 0, NCX_EL_MESSAGE_ID);
    if (attr) {
        dlq_remove(attr);
        xml_free_attr(attr);
    }

    /* setup the prefix map with the NETCONF (and maybe NCX) namespace */
    res = xml_msg_build_prefix_map(&msg, 
                                   &req->attrs, 
                                   FALSE, 
                                   (req->data->nsid == xmlns_ncx_id()));

    /* add the message-id attribute */
    if (res == NO_ERR) {
        res = xml_add_attr(&req->attrs, 
                           0, 
                           NCX_EL_MESSAGE_ID,
                           req->msg_id);
    }

    /* set perf timestamp in case response timing active */
    gettimeofday(&req->perfstarttime, NULL);     

    /* send the <?xml?> directive */
    if (res == NO_ERR) {
        res = ses_start_msg(scb);
    }

    /* start the <rpc> element */
    if (res == NO_ERR) {
        anyout = TRUE;
        xml_wr_begin_elem_ex(scb, 
                             &msg, 
                             0, 
                             nc_id, 
                             NCX_EL_RPC, 
                             &req->attrs, 
                             ATTRQ, 
                             0, 
                             START);
    }
    
    /* send the method and parameters */
    if (res == NO_ERR) {
        xml_wr_full_val(scb, &msg, req->data, NCX_DEF_INDENT);
    }

    /* finish the <rpc> element */
    if (res == NO_ERR) {
        xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_RPC, 0);
    }

    /* finish the message */
    if (anyout) {
        ses_finish_msg(scb);
    }

    if (res == NO_ERR) {
        req->replycb = rpyfn;
        add_request(scb, req);
    }

    xml_msg_clean_hdr(&msg);
    return res;

}  /* mgr_rpc_send_request */
Пример #20
0
void InvitationManager::handle_receive_request_list(cmd_data_pointer data)
{
    std::shared_ptr<net_data_recv_package> rec = dynamic_pointer_cast<net_data_recv_package>(data);
    auto processor = PM->ReceiveRequestList_down(rec);
    add_request(processor);
}
char *
nm_dhcp_dhclient_create_config (const char *interface,
                                gboolean is_ip6,
                                GBytes *client_id,
                                const char *anycast_addr,
                                const char *hostname,
                                const char *fqdn,
                                const char *orig_path,
                                const char *orig_contents,
                                GBytes **out_new_client_id)
{
	GString *new_contents;
	GPtrArray *fqdn_opts, *reqs;
	int i;

	g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL);

	new_contents = g_string_new (_("# Created by NetworkManager\n"));
	fqdn_opts = g_ptr_array_sized_new (5);
	reqs = g_ptr_array_new_full (5, g_free);

	if (orig_contents) {
		char **lines, **line;
		gboolean in_alsoreq = FALSE;
		gboolean in_req = FALSE;

		g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path);

		lines = g_strsplit_set (orig_contents, "\n\r", 0);
		for (line = lines; lines && *line; line++) {
			char *p = *line;

			if (!strlen (g_strstrip (p)))
				continue;

			if (!strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) {
				/* Override config file "dhcp-client-id" and use one from the connection */
				if (client_id)
					continue;

				/* Otherwise capture and return the existing client id */
				if (out_new_client_id)
					*out_new_client_id = read_client_id (p);
			}

			/* Override config file hostname and use one from the connection */
			if (hostname || fqdn) {
				if (strncmp (p, HOSTNAME4_TAG, strlen (HOSTNAME4_TAG)) == 0)
					continue;
				if (strncmp (p, FQDN_TAG, strlen (FQDN_TAG)) == 0)
					continue;
			}

			/* To let user's FQDN options (except "fqdn.fqdn") override the
			 * default ones set by NM, add them later
			 */
			if (!strncmp (p, FQDN_TAG_PREFIX, NM_STRLEN (FQDN_TAG_PREFIX))) {
				g_ptr_array_add (fqdn_opts, g_strdup (p + NM_STRLEN (FQDN_TAG_PREFIX)));
				continue;
			}

			/* Ignore 'script' since we pass our own */
			if (g_str_has_prefix (p, "script "))
				continue;

			/* Check for "request" */
			if (!strncmp (p, REQ_TAG, strlen (REQ_TAG))) {
				in_req = TRUE;
				p += strlen (REQ_TAG);
				g_ptr_array_set_size (reqs, 0);
			}

			/* Save all request options for later use */
			if (in_req) {
				in_req = !grab_request_options (reqs, p);
				continue;
			}

			/* Check for "also require" */
			if (!strncmp (p, ALSOREQ_TAG, strlen (ALSOREQ_TAG))) {
				in_alsoreq = TRUE;
				p += strlen (ALSOREQ_TAG);
			}

			if (in_alsoreq) {
				in_alsoreq = !grab_request_options (reqs, p);
				continue;
			}

			/* Existing configuration line is OK, add it to new configuration */
			g_string_append (new_contents, *line);
			g_string_append_c (new_contents, '\n');
		}

		if (lines)
			g_strfreev (lines);
	} else
		g_string_append_c (new_contents, '\n');

	if (is_ip6) {
		add_hostname6 (new_contents, hostname);
		add_request (reqs, "dhcp6.name-servers");
		add_request (reqs, "dhcp6.domain-search");
		add_request (reqs, "dhcp6.client-id");
	} else {
		add_ip4_config (new_contents, client_id, hostname, fqdn);
		add_request (reqs, "rfc3442-classless-static-routes");
		add_request (reqs, "ms-classless-static-routes");
		add_request (reqs, "static-routes");
		add_request (reqs, "wpad");
		add_request (reqs, "ntp-servers");
	}

	/* And add it to the dhclient configuration */
	for (i = 0; i < reqs->len; i++)
		g_string_append_printf (new_contents, "also request %s;\n", (char *) reqs->pdata[i]);
	g_ptr_array_free (reqs, TRUE);

	for (i = 0; i < fqdn_opts->len; i++) {
		char *t = g_ptr_array_index (fqdn_opts, i);

		if (i == 0)
			g_string_append_printf (new_contents, "\n# FQDN options from %s\n", orig_path);
		g_string_append_printf (new_contents, FQDN_TAG_PREFIX "%s\n", t);
		g_free (t);
	}
	g_ptr_array_free (fqdn_opts, TRUE);

	g_string_append_c (new_contents, '\n');

	if (anycast_addr) {
		g_string_append_printf (new_contents, "interface \"%s\" {\n"
		                        " initial-interval 1; \n"
		                        " anycast-mac ethernet %s;\n"
		                        "}\n",
		                        interface, anycast_addr);
	}

	return g_string_free (new_contents, FALSE);
}
Пример #22
0
static void cmdline(int argc, char * const argv[])
{
  int exit_status = EXIT_FAILURE;

  enum opt { OPT_PUSH   = 'p',
             OPT_POP    = 'P',
             OPT_CLEAN  = 'c',
             OPT_GET    = 'g',
             OPT_GETALL = 'G',
             OPT_SIZE   = 's',
             OPT_INFO   = 'i',
             OPT_HELP   = 'h' };

  struct opts_name names[] = {
    { 'p', "push",    "Push a message" },
    { 'P', "pop",     "Pop a message from the stack" },
    { 'c', "clean",   "Clean the stack" },
    { 'g', "get",     "Get a message, without removing it" },
    { 'G', "get-all", "Get and print all message from the stack" },
    { 's', "size",    "Get the stack size" },
    { 'i', "info",    "Get informations about the server" },
    { 'h', "help",    "Show this help message" },
    { 0, NULL, NULL }
  };

  struct option opts[] = {
    { "push",    optional_argument, NULL, OPT_PUSH },
    { "pop",     optional_argument, NULL, OPT_POP },
    { "clean",   no_argument, NULL, OPT_CLEAN },
    { "get",     optional_argument, NULL, OPT_GET },
    { "get-all", no_argument, NULL, OPT_GETALL },
    { "size",    no_argument, NULL, OPT_SIZE },
    { "info",    no_argument, NULL, OPT_INFO },
    { "help",    no_argument, NULL, OPT_HELP },
    { NULL, 0, NULL, 0 }
  };

  while(1) {
    int c = getopt_long(argc, argv, "p::P::cg::Gsih", opts, NULL);

    if(c == -1)
      break;

    switch(c) {
    case(OPT_PUSH):
      if(optarg)
        add_request(CMD_PUSH, optarg, 0);
      else
        errx(EXIT_FAILURE, "Not implemented...");
      break;
    case(OPT_POP):
      if(optarg)
        add_request(CMD_POP, NULL, atoi(optarg));
      else
        add_request(CMD_POPF, NULL, 0);
      break;
    case(OPT_CLEAN):
      add_request(CMD_CLEAN, NULL, 0);
      break;
    case(OPT_GET):
      if(optarg)
        add_request(CMD_GET, NULL, atoi(optarg));
      else
        add_request(CMD_GETF, NULL, 0);
      break;
    case(OPT_GETALL):
      add_request(CMD_GETALL, NULL, 0);
      break;
    case(OPT_SIZE):
      add_request(CMD_SIZE, NULL, 0);
      break;
    case(OPT_INFO):
      add_request(CMD_NBCLI, NULL, 0);
      add_request(CMD_NBSRV, NULL, 0);
      add_request(CMD_NBRCV, NULL, 0);
      add_request(CMD_NBSND, NULL, 0);
      add_request(CMD_NBERR, NULL, 0);
      add_request(CMD_MAXNSEC, NULL, 0);
      add_request(CMD_MINNSEC, NULL, 0);
      add_request(CMD_SUMNSEC, NULL, 0);
      break;
    case(OPT_HELP):
      exit_status = EXIT_SUCCESS;
    default:
      help(names);
      exit(exit_status);
    }
  }

  /* consider remaining argument as socket path */
  if(argc - optind != 1)
    errx(EXIT_FAILURE, "except socket path");
  sock_path = argv[optind];
}
Пример #23
0
int session_io_handler(Session *s){
struct gg_event *event;
char *jid,*str;
int chat;
GIOCondition condition=s->g_pollfd.revents;
time_t timestamp;
gboolean state;

	user_load_locale(s->user);
	debug(L_("Checking error conditions..."));
	if (condition&(G_IO_ERR|G_IO_NVAL)){
		if (condition&G_IO_ERR) g_warning(N_("Error on connection for %s, GGid: %i"),s->jid,s->ggs->uin);
		if (condition&G_IO_HUP){
			g_warning(N_("Hangup on connection for %s, GGid: %i"),s->jid,s->ggs->uin);
			return session_error(s);
		}
		if (condition&G_IO_NVAL) g_warning(N_("Invalid channel on connection for %s"),s->jid);

		session_broken(s);
		return FALSE;
	}

	debug(L_("watching fd (gg_debug_level=%i)..."),gg_debug_level);
	event=gg_watch_fd(s->ggs);
	if (!event){
		g_warning(N_("Connection broken. Session of %s, GGid: %i"),s->jid,s->ggs->uin);
		return session_error(s);
	}

	switch(event->type){
		case GG_EVENT_DISCONNECT:
			g_warning(N_("Server closed connection of %s, GGid: %i"),s->jid,s->ggs->uin);
			session_error(s);
			gg_event_free(event);
			return FALSE;
		case GG_EVENT_CONN_FAILED:
			g_message(N_("Login failed (%d:%s) for %s, GGid: %i"),
					event->event.failure,
					(event->event.failure>GG_FAILURE_NUM_REASONS||event->event.failure<1)?"-UNKNOWN-":gg_failure_reason[event->event.failure-1],
					s->jid,
					s->ggs->uin);
			if (s->req_id)
				jabber_iq_send_error(s->s,s->jid,NULL,s->req_id,401,_("Unauthorized"));
			else {
				str=g_strdup(from_utf8(gg_failure_reason_txt[event->event.failure-1]));
				presence_send(s->s,NULL,s->user->jid,0,NULL,str,0);
				g_free(str);
			}
			state = FALSE;
			if (!s->req_id)
				switch(event->event.failure){
					case GG_FAILURE_RESOLVING:
					case GG_FAILURE_CONNECTING:
					case GG_FAILURE_INVALID:
					case GG_FAILURE_READING:
					case GG_FAILURE_WRITING:
					case GG_FAILURE_TLS:
						state = session_try_next(s);
					default:
						break;
				}
			if (state) {
				s->connected=0;
				session_schedule_reconnect(s);
			} else
				session_remove(s);
			gg_event_free(event);
			return FALSE;
		case GG_EVENT_CONN_SUCCESS:
			g_message(L_("Login succeed for %s, GGid: %i"),s->jid,s->ggs->uin);
			if (s->req_id)
				jabber_iq_send_result(s->s,s->jid,NULL,s->req_id,NULL);
			if (s->req_id){
				g_free(s->req_id);
				s->req_id=NULL;
			}
			if (s->query){
				xmlnode_free(s->query);
				s->query=NULL;
			}
			if (!s->user->confirmed){
				s->user->confirmed=1;
				user_save(s->user);
			}
			s->connected=1;
			session_send_status(s);
			session_send_notify(s);
			presence_send(s->s,NULL,s->user->jid,s->user->invisible?-1:1,NULL,s->gg_status_descr,0);

			if (s->timeout_func) g_source_remove(s->timeout_func);
			s->timeout_func=NULL;
			if (s->ping_timeout_func) g_source_remove(s->ping_timeout_func);
			s->ping_timeout_func=g_timeout_add(ping_interval*1000,session_ping,s);
			if (s->pubdir_change){
				add_request(RT_CHANGE,s->jid,NULL,s->req_id,
							NULL,s->pubdir_change,s->s);
				gg_pubdir50_free(s->pubdir_change);
				s->pubdir_change=NULL;
			}
			if (s->get_roster){
				gg_userlist_request(s->ggs, GG_USERLIST_GET, NULL);
			}
			break;
		case GG_EVENT_NOTIFY:
			session_event_notify(s,event);
			break;
		case GG_EVENT_NOTIFY_DESCR:
			session_event_notify_descr(s,event);
			break;
		case GG_EVENT_NOTIFY60:
			session_event_notify60(s,event);
			break;
		case GG_EVENT_STATUS:
			session_event_status(s,
					event->event.status.status,
					event->event.status.uin,
					event->event.status.descr,
					0,0,0,0);
			break;
		case GG_EVENT_STATUS60:
			session_event_status(s,
					event->event.status60.status,
					event->event.status60.uin,
					event->event.status60.descr,
					1,
					event->event.status60.remote_ip,
					event->event.status60.remote_port,
					event->event.status60.version);
			break;
		case GG_EVENT_MSG:
			if (event->event.msg.recipients_count>1){
				debug(L_("Dropped conference message: sender: %i class: %i time: %lu"),
							event->event.msg.sender,
							event->event.msg.msgclass,
							(unsigned long)event->event.msg.time);
				break;
			}
			gg_messages_in++;
			debug(L_("Message: sender: %i class: %i time: %lu"),
							event->event.msg.sender,
							event->event.msg.msgclass,
							(unsigned long)event->event.msg.time);
			
			if (event->event.msg.sender==0){
				if (!user_sys_msg_received(s->user,event->event.msg.msgclass)) break;
				if (ignore_system_messages == ISM_IGNORE_ALL) break;
				if (ignore_system_messages == ISM_IGNORE_HTML
					&& strstr((const char *)event->event.msg.message, "<HTML>")) break;
				timestamp=event->event.msg.time;
				str=g_strdup_printf(_("GG System message #%i"),
							event->event.msg.msgclass);
				message_send_subject(s->s,jid, s->user->jid, str,
						string_from_gg((const char *)event->event.msg.message),
												timestamp);
				g_free(str);
				break;
			}
			else{
				Contact *c=user_get_contact(s->user,
						event->event.msg.sender,0);
				if ((!c && s->user->ignore_unknown) 
				    || (c && c->ignored)) {
					debug(L_("Ignoring the message."));
			       		break;
				}
				jid=jid_build_full(event->event.msg.sender);
				if ((event->event.msg.msgclass&GG_CLASS_CHAT)!=0) chat=1;
				else chat=0;
			}
			if ((event->event.msg.msgclass&GG_CLASS_QUEUED)!=0){
				timestamp=event->event.msg.time;
			}
			else timestamp=0;
			if(event->event.msg.formats_length>0)
				message_send_rich(s->s,jid,s->user->jid,chat,
						(char *)event->event.msg.message,timestamp,
						event->event.msg.formats_length,(void *)event->event.msg.formats);
			else
				message_send(s->s,jid,s->user->jid,chat,
						string_from_gg((const char *)event->event.msg.message),timestamp);
			g_free(jid);
			break;
		case GG_EVENT_PONG:
			s->waiting_for_pong=FALSE;
			if (s->ping_timer){
				g_timer_stop(s->ping_timer);
				debug(L_("Pong! ping time: %fs"),
						g_timer_elapsed(s->ping_timer,NULL));
			}
			if (s->timeout_func) g_source_remove(s->timeout_func);
			s->timeout_func=NULL;
			break;
		case GG_EVENT_PUBDIR50_SEARCH_REPLY:
			request_response_search(event);
			break;
		case GG_EVENT_PUBDIR50_WRITE:
			request_response_write(event);
			break;
		case GG_EVENT_ACK:
			debug("GG_EVENT_ACK");
			break;
		case GG_EVENT_NONE:
			debug("GG_EVENT_NONE");
			break;
		case GG_EVENT_USERLIST:
			if(event->event.userlist.type==GG_USERLIST_GET_REPLY)
				get_roster_done(s,event);
			else
				g_warning(N_("Wrong gg userlist type: %i"),event->event.userlist.type);
			break;
		default:
			g_warning(N_("Unknown GG event: %i"),event->type);
			break;
	}

	session_setup_g_source(s);

	gg_event_free(event);
	debug(L_("io handler done..."));

	return FALSE;
}
Пример #24
0
static int
dissect_ipmi_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		gint hf_parent_item, gint ett_tree, const ipmi_context_t * ctx)
{
	ipmi_packet_data_t * data;
	ipmi_netfn_t * cmd_list;
	ipmi_cmd_t * cmd;
	proto_item * ti;
	proto_tree * cmd_tree = NULL, * tmp_tree;
	guint8 prev_level, cc_val;
	guint offset, siglen, is_resp;
	const char * cc_str, * netfn_str;

	/* get packet data */
	data = get_packet_data(pinfo);
	if (!data) {
		return 0;
	}

	/* get prefix length */
	siglen = ipmi_getsiglen(ctx->hdr.netfn);

	/* get response flag */
	is_resp = ctx->hdr.netfn & 1;

	/* check message length */
	if (tvb_captured_length(tvb) < ctx->hdr_len + siglen + is_resp
			+ !(ctx->flags & IPMI_D_NO_CKS)) {
		/* don bother with anything */
		return call_data_dissector(tvb, pinfo, tree);
	}

	/* save nest level */
	prev_level = data->curr_level;

	/* assign next nest level */
	data->curr_level = data->next_level;

	/* increment next nest level */
	data->next_level++;

	/* check for the first invocation */
	if (!data->curr_level) {
		/* get current frame data */
		data->curr_frame = get_frame_data(data, pinfo->num);
		data->curr_frame_num = pinfo->num;

		/* copy frame timestamp */
		memcpy(&data->curr_frame->ts, &pinfo->abs_ts, sizeof(nstime_t));

		/* cache channel and direction */
		data->curr_channel = ctx->hdr.channel;
		data->curr_dir = ctx->hdr.dir;

		/* remove requests which are too old */
		remove_old_requests(data, &pinfo->abs_ts);
	}

	if (data->curr_level < MAX_NEST_LEVEL) {
		if (ctx->hdr.netfn & 1) {
			/* perform request/response matching */
			match_request_response(data, &ctx->hdr, ctx->flags);
		} else {
			/* add request to the list for later matching */
			add_request(data, &ctx->hdr);
		}
	}

	/* get command list by network function code */
	cmd_list = ipmi_getnetfn(ctx->hdr.netfn,
			tvb_get_ptr(tvb, ctx->hdr_len + is_resp, siglen));

	/* get command descriptor */
	cmd = ipmi_getcmd(cmd_list, ctx->hdr.cmd);

	/* check if response */
	if (is_resp) {
		/* get completion code */
		cc_val = tvb_get_guint8(tvb, ctx->hdr_len);

		/* get completion code desc */
		cc_str = ipmi_get_completion_code(cc_val, cmd);
	} else {
		cc_val = 0;
		cc_str = NULL;
	}

	/* check if not inside a message */
	if (!data->curr_level) {
		/* add packet info */
		add_command_info(pinfo, cmd, is_resp, cc_val, cc_str,
				ctx->flags & IPMI_D_BROADCAST ? TRUE : FALSE);
	}

	if (tree) {
		/* add parent node */
		if (!data->curr_level) {
			ti = proto_tree_add_item(tree, hf_parent_item, tvb, 0, -1, ENC_NA);
			cmd_tree = proto_item_add_subtree(ti, ett_tree);
		} else {
			char str[ITEM_LABEL_LENGTH];

			if (is_resp) {
				g_snprintf(str, ITEM_LABEL_LENGTH, "Rsp, %s, %s",
						cmd->desc, cc_str);
			} else {
				g_snprintf(str, ITEM_LABEL_LENGTH, "Req, %s", cmd->desc);
			}
			if (proto_registrar_get_ftype(hf_parent_item) == FT_STRING) {
				ti = proto_tree_add_string(tree, hf_parent_item, tvb, 0, -1, str);
				cmd_tree = proto_item_add_subtree(ti, ett_tree);
			}
			else
				cmd_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tree, NULL, str);
		}

		if (data->curr_level < MAX_NEST_LEVEL) {
			/* check if response */
			if (ctx->hdr.netfn & 1) {
				/* get current command data */
				ipmi_cmd_data_t * rs_data =
						data->curr_frame->cmd_data[data->curr_level];

				if (rs_data->matched_frame_num) {
					nstime_t ns;

					/* add "Request to:" field */
					ti = proto_tree_add_uint(cmd_tree, hf_ipmi_response_to,
							tvb, 0, 0, rs_data->matched_frame_num);

					/* mark field as a generated one */
					PROTO_ITEM_SET_GENERATED(ti);

					/* calculate delta time */
					nstime_delta(&ns, &pinfo->abs_ts,
							&get_frame_data(data,
									rs_data->matched_frame_num)->ts);

					/* add "Response time" field */
					ti = proto_tree_add_time(cmd_tree, hf_ipmi_response_time,
							tvb, 0, 0, &ns);

					/* mark field as a generated one */
					PROTO_ITEM_SET_GENERATED(ti);
					}
			} else {
				/* get current command data */
				ipmi_cmd_data_t * rq_data =
						data->curr_frame->cmd_data[data->curr_level];

				if (rq_data->matched_frame_num) {
					/* add "Response in:" field  */
					ti = proto_tree_add_uint(cmd_tree, hf_ipmi_response_in,
							tvb, 0, 0, rq_data->matched_frame_num);

					/* mark field as a generated one */
					PROTO_ITEM_SET_GENERATED(ti);
				}
			}
		}

		/* set starting offset */
		offset = 0;

		/* check if message is broadcast */
		if (ctx->flags & IPMI_D_BROADCAST) {
			/* skip first byte */
			offset++;
		}

		/* check if session handle is specified */
		if (ctx->flags & IPMI_D_SESSION_HANDLE) {
			/* add session handle field */
			proto_tree_add_item(cmd_tree, hf_ipmi_session_handle,
					tvb, offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* check if responder address is specified */
		if (ctx->flags & IPMI_D_TRG_SA) {
			/* add response address field */
			proto_tree_add_item(cmd_tree, hf_ipmi_header_trg, tvb,
					offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* get NetFn string */
		netfn_str = ipmi_getnetfnname(ctx->hdr.netfn, cmd_list);

		/* Network function + target LUN */
		tmp_tree = proto_tree_add_subtree_format(cmd_tree, tvb, offset, 1,
				ett_header_byte_1, NULL, "Target LUN: 0x%02x, NetFN: %s %s (0x%02x)",
				ctx->hdr.rs_lun, netfn_str,
				is_resp ? "Response" : "Request", ctx->hdr.netfn);

		/* add Net Fn */
		proto_tree_add_uint_format(tmp_tree, hf_ipmi_header_netfn, tvb,
				offset, 1, ctx->hdr.netfn << 2,
				"NetFn: %s %s (0x%02x)", netfn_str,
				is_resp ? "Response" : "Request", ctx->hdr.netfn);

		proto_tree_add_item(tmp_tree, hf_ipmi_header_trg_lun, tvb,
				offset++, 1, ENC_LITTLE_ENDIAN);

		/* check if cks1 is specified */
		if (!(ctx->flags & IPMI_D_NO_CKS)) {
			guint8 cks = tvb_get_guint8(tvb, offset);

			/* Header checksum */
			if (ctx->cks1) {
				guint8 correct = cks - ctx->cks1;

				proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_crc,
						tvb, offset++, 1, cks,
						"0x%02x (incorrect, expected 0x%02x)", cks, correct);
			} else {
				proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_crc,
						tvb, offset++, 1, cks,
						"0x%02x (correct)", cks);
			}
		}

		/* check if request address is specified */
		if (!(ctx->flags & IPMI_D_NO_RQ_SA)) {
			/* add request address field */
			proto_tree_add_item(cmd_tree, hf_ipmi_header_src, tvb,
					offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* check if request sequence is specified */
		if (!(ctx->flags & IPMI_D_NO_SEQ)) {
			/* Sequence number + source LUN */
			tmp_tree = proto_tree_add_subtree_format(cmd_tree, tvb, offset, 1,
					ett_header_byte_4, NULL, "%s: 0x%02x, SeqNo: 0x%02x",
					(ctx->flags & IPMI_D_TMODE) ? "Bridged" : "Source LUN",
							ctx->hdr.rq_lun, ctx->hdr.rq_seq);

			if (ctx->flags & IPMI_D_TMODE) {
				proto_tree_add_item(tmp_tree, hf_ipmi_header_bridged,
						tvb, offset, 1, ENC_LITTLE_ENDIAN);
			} else {
				proto_tree_add_item(tmp_tree, hf_ipmi_header_src_lun,
						tvb, offset, 1, ENC_LITTLE_ENDIAN);
			}

			/* print seq no */
			proto_tree_add_item(tmp_tree, hf_ipmi_header_sequence, tvb,
					offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* command code */
		proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_command,
				tvb, offset++, 1, ctx->hdr.cmd, "%s (0x%02x)",
				cmd->desc, ctx->hdr.cmd);

		if (is_resp) {
			/* completion code */
			proto_tree_add_uint_format_value(cmd_tree,
					hf_ipmi_header_completion, tvb, offset++, 1,
					cc_val, "%s (0x%02x)", cc_str, cc_val);
		}

		if (siglen) {
			/* command prefix (if present) */
			ti = proto_tree_add_item(cmd_tree, hf_ipmi_header_sig, tvb,
					offset, siglen, ENC_NA);
			proto_item_append_text(ti, " (%s)", netfn_str);
		}
	}

	if (tree || (cmd->flags & CMD_CALLRQ)) {
		/* calculate message data length */
		guint data_len = tvb_captured_length(tvb)
				- ctx->hdr_len
				- siglen
				- (is_resp ? 1 : 0)
				- !(ctx->flags & IPMI_D_NO_CKS);

		/* create data subset */
		tvbuff_t * data_tvb = tvb_new_subset_length(tvb,
				ctx->hdr_len + siglen + (is_resp ? 1 : 0), data_len);

		/* Select sub-handler */
		ipmi_cmd_handler_t hnd = is_resp ? cmd->parse_resp : cmd->parse_req;

		if (hnd && tvb_captured_length(data_tvb)) {
			/* create data field */
			tmp_tree = proto_tree_add_subtree(cmd_tree, data_tvb, 0, -1, ett_data, NULL, "Data");

			/* save current command */
			data->curr_hdr = &ctx->hdr;

			/* save current completion code */
			data->curr_ccode = cc_val;

			/* call command parser */
			hnd(data_tvb, pinfo, tmp_tree);
		}
	}

	/* check if cks2 is specified */
	if (tree && !(ctx->flags & IPMI_D_NO_CKS)) {
		guint8 cks;

		/* get cks2 offset */
		offset = tvb_captured_length(tvb) - 1;

		/* get cks2 */
		cks = tvb_get_guint8(tvb, offset);

		/* Header checksum */
		if (ctx->cks2) {
			guint8 correct = cks - ctx->cks2;

			proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_data_crc,
					tvb, offset, 1, cks,
					"0x%02x (incorrect, expected 0x%02x)", cks, correct);
		} else {
			proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_data_crc,
					tvb, offset, 1, cks,
					"0x%02x (correct)", cks);
		}
	}

	/* decrement next nest level */
	data->next_level = data->curr_level;

	/* restore previous nest level */
	data->curr_level = prev_level;

	return tvb_captured_length(tvb);
}
Пример #25
0
/* like any C program, program's execution begins in main */
int
main(int argc, char* argv[])
{
    int        i;                                /* loop counter          */
    struct timespec delay;			 /* used for wasting time */
    struct requests_queue* requests = NULL;  /* pointer to requests queue */
    struct handler_threads_pool* handler_threads = NULL;
					       /* list of handler threads */

    /* create the requests queue */
    requests = init_requests_queue(&request_mutex, &got_request);
    assert(requests);

    /* create the handler threads list */
    handler_threads =
	init_handler_threads_pool(&request_mutex, &got_request, requests);
    assert(handler_threads);

    /* create the request-handling threads */
    for (i=0; i<NUM_HANDLER_THREADS; i++) {
	add_handler_thread(handler_threads);
    }

    /* run a loop that generates requests */
    for (i=0; i<600; i++) {
	int num_requests; // number of requests waiting to be handled.
	int num_threads;  // number of active handler threads.

	add_request(requests, i);

	num_requests = get_requests_number(requests);
	num_threads = get_handler_threads_number(handler_threads);

	/* if there are too many requests on the queue, spawn new threads */
	/* if there are few requests and too many handler threads, cancel */
	/* a handler thread.          					  */
	if (num_requests > HIGH_REQUESTS_WATERMARK &&
	    num_threads < MAX_NUM_HANDLER_THREADS) {
		printf("main: adding thread: '%d' requests, '%d' threads\n",
		       num_requests, num_threads);
		add_handler_thread(handler_threads);
	}
	if (num_requests < LOW_REQUESTS_WATERMARK &&
		 num_threads > NUM_HANDLER_THREADS) {
	    printf("main: deleting thread: '%d' requests, '%d' threads\n",
		   num_requests, num_threads);
	    delete_handler_thread(handler_threads);
	}

	/* pause execution for a little bit, to allow      */
	/* other threads to run and handle some requests.  */
	if (rand() > 3*(RAND_MAX/4)) { /* this is done about 25% of the time */
	    delay.tv_sec = 0;
	    delay.tv_nsec = 1;
	    nanosleep(&delay, NULL);
	}
    }
    /* modify the flag to tell the handler threads no   */
    /* new requests will be generated.                  */
    {
        int rc;

        rc = pthread_mutex_lock(&request_mutex);
        done_creating_requests = 1;
        rc = pthread_cond_broadcast(&got_request);
        rc = pthread_mutex_unlock(&request_mutex);
    }

    /* cleanup */
    delete_handler_threads_pool(handler_threads);
    delete_requests_queue(requests);
    
    printf("Glory,  we are done.\n");

    return 0;
}
Пример #26
0
Файл: rats.c Проект: nesl/sos-2x
static int8_t module(void *state, Message *msg)
{
    app_state_t *s = (app_state_t *) state;
	MsgParam *p = (MsgParam*)(msg->data);
	
    /**
     * Switch to the correct message handler
     */
    switch (msg->type){

        case MSG_INIT:
		{
			DEBUG("RATS: node %d initializing\n", ker_id());
			s->pid = msg->did;
			s->ts_list = NULL;
			s->ts_packet.type = NORMAL_PACKET;

			//Notify neighbors that RATS is starting (in case node rebooted while it was
			//synchronizing with another node
			post_net(s->pid, s->pid, MSG_INVALIDATE_ENTRY, 0, NULL, 0, BCAST_ADDRESS);
			return SOS_OK;
		}
		case MSG_RATS_CLIENT_START:
		{
			MsgParam *p  = (MsgParam *)msg->data;
			DEBUG("RATS: Received MSG_RATS_CLIENT_START for node %d\n", p->word);
			
			uint8_t request_status = add_request(s, p->word, p->byte);

			//If a new request was created, then send packet to parent
			if(request_status != NO_REQUEST_CREATED)
			{
				DEBUG("RATS: Transmitting request to node %d\n", p->word);
				LED_DBG(LED_RED_TOGGLE);
				//If the current node is the parent of the target node, then the target node will
				//reply by informing the parent, who will add the target to its list of children.
				post_net(s->pid, s->pid, MSG_RATS_SERVER_START, 0, NULL, 0, p->word);
			}
			else
			{
				//Request already exists
				DEBUG("RATS: Request already exists\n");
			}
			
			//If this was the first request that was created, we need to start the panic timer
			if(request_status == CREATED_FIRST_REQUEST)
			{
				DEBUG("RATS: PANIC_TIMER started\n");
				
				#ifdef USE_PANIC_PACKETS
				sys_timer_start(PANIC_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT);
				#endif //USE_PANIC_PACKETS
			}			

			return SOS_OK;
		}
		case MSG_RATS_SERVER_START:
		{
			timesync_t * temp_ts_ptr = get_timesync_ptr(s, msg->saddr);

			DEBUG("RATS: Received request from node %d\n", msg->saddr);
			
			if(temp_ts_ptr == NULL)
			{
				DEBUG("RATS: Starting timesync with node %d\n", msg->saddr);
				LED_DBG(LED_RED_TOGGLE);
				//If request is coming from node, with whom the node is not synchronizing, then
				//synchronization is starting
				sys_timer_stop(TRANSMIT_TIMER);
				sys_timer_stop(VALIDATION_TIMER);				
				s->ts_packet.transmission_period = INITIAL_TRANSMISSION_PERIOD;	
				s->ts_packet.min_period_node_id = msg->saddr;	
				s->transmit_timer_counter = 1; //s->ts_packet.transmission_period/INITIAL_TRANSMISSION_PERIOD;
				s->validation_timer_counter = 5; //s->transmit_timer_counter + 4;
				s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS;
				sys_timer_start(TRANSMIT_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT);	
				sys_timer_start(VALIDATION_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT);				
			}

			return SOS_OK;
		}
		case MSG_RATS_GET_TIME:
		{
			//If the module passed a NULL pointer or if the data size is wrong, then discard
			if( (msg->data == NULL) 
			#ifndef PC_PLATFORM
			 || (msg->len != sizeof(rats_t) ) 
			#endif //PC_PLATFORM
			 )
			{
				DEBUG("RATS: Invalid data received in MSG_RATS_GET_TIME\n");
				break;
			}
			rats_t * rats_ptr = (rats_t *)sys_msg_take_data(msg);
			DEBUG("RATS: Received MSG_RATS_GET_TIME (mod_id=%d node=%d)\n", rats_ptr->mod_id, msg->saddr);			
			
			if(rats_ptr->source_node_id == ker_id())
			{
				timesync_t * temp_ts_ptr = get_timesync_ptr(s, rats_ptr->target_node_id);
				if(temp_ts_ptr == NULL)
				{
					DEBUG("RATS: Target node %d is not time synced\n", rats_ptr->target_node_id);
					sys_free(rats_ptr);
					break;
				}
				else
				{
					DEBUG("RATS: Calculating time for target node %d locally\n", rats_ptr->target_node_id);
					if(temp_ts_ptr->packet_count < BUFFER_SIZE) // learning state
					{
						rats_ptr->time_at_target_node = 0;
						rats_ptr->error = 0;
					}
					else
					{
						rats_ptr->time_at_target_node = convert_from_mine_to_parent_time(rats_ptr->time_at_source_node, rats_ptr->target_node_id);
						rats_ptr->error	= getError(&temp_ts_ptr->timestamps[0], &temp_ts_ptr->my_time[0], BUFFER_SIZE,
							temp_ts_ptr->window_size, BUFFER_SIZE - temp_ts_ptr->window_size, &temp_ts_ptr->a, &temp_ts_ptr->b, temp_ts_ptr->sampling_period, FALSE);
					}
				}
			}
			else if (rats_ptr->target_node_id == ker_id())
			{
				timesync_t * temp_ts_ptr = get_timesync_ptr(s, rats_ptr->source_node_id);
				if(temp_ts_ptr == NULL)
				{
					DEBUG("RATS: Source node %d is not time synced\n", rats_ptr->source_node_id);
					sys_free(rats_ptr);
					break;
				}
				else
				{
					DEBUG("RATS: Calculating time for source node %d locally\n", rats_ptr->source_node_id);
					if(temp_ts_ptr->packet_count < BUFFER_SIZE) // learning state
					{
						rats_ptr->time_at_target_node = 0;
						rats_ptr->error = 0;
					}
					else
					{
						rats_ptr->time_at_target_node = convert_from_parent_to_my_time(rats_ptr->time_at_source_node, rats_ptr->source_node_id);
						rats_ptr->error	= getError(&temp_ts_ptr->timestamps[0], &temp_ts_ptr->my_time[0], BUFFER_SIZE,
							temp_ts_ptr->window_size, BUFFER_SIZE - temp_ts_ptr->window_size, &temp_ts_ptr->a, &temp_ts_ptr->b, temp_ts_ptr->sampling_period, TRUE);
					}
				}
				
			}
			else
			{
				DEBUG("RATS: Invalid request (source = %d, target - %d)\n", rats_ptr->source_node_id, rats_ptr->target_node_id);
				sys_free(rats_ptr);
				break;
			}

			DEBUG("RATS: Sending reply to module %d\n", rats_ptr->mod_id);
			post_long(rats_ptr->mod_id, s->pid, rats_ptr->msg_type, sizeof(rats_t), rats_ptr, SOS_MSG_RELEASE);
			break;
		}
		case MSG_RATS_CLIENT_STOP:
		{
			MsgParam *p  = (MsgParam *)msg->data;
			uint16_t node_id = p->word;
			
			//First we need to remove node from list of parents
			/* Select node at head of list */
			timesync_t * ts_list_ptr = s->ts_list;
			timesync_t * ts_delete_list_ptr;
			timesync_t * ts_previous_list_ptr = s->ts_list;
		
			/* Loop until we've reached the end of the list */
			while( ts_list_ptr != NULL )
			{
				if(ts_list_ptr->node_id == node_id)
				{
					if(--ts_list_ptr->ref_counter > 0)
						return SOS_OK;
					
					DEBUG("RATS: Removing node %d from list of parents. Sending MSG_RATS_SERVER_STOP.\n", node_id);
					post_net(s->pid, s->pid, MSG_RATS_SERVER_STOP, 0, NULL, 0, node_id);

					/* Found the item to be deleted,
		     		 re-link the list around it */
					if( ts_list_ptr == s->ts_list )
						/* We're deleting the head */
						s->ts_list = ts_list_ptr->next;
					else
						ts_previous_list_ptr->next = ts_list_ptr->next;
		
					ts_delete_list_ptr = ts_list_ptr;
					ts_list_ptr = ts_list_ptr->next;
					
					/* Free the node */
					sys_free( ts_delete_list_ptr );
					
					//If the parent list is empty, then we're stopping the panic timer
					if(s->ts_list == NULL)
					{
						DEBUG("RATS: Parent list is empty. Stopping panic timer\n");
						
						#ifdef USE_PANIC_PACKETS
						sys_timer_stop(PANIC_TIMER);
						#endif //USE_PANIC_PACKETS
					}					
					
					return SOS_OK;
				}
				ts_previous_list_ptr = ts_list_ptr;
				ts_list_ptr = ts_list_ptr->next;
			}
			
			DEBUG("RATS: Requested parent %d was not found\n", node_id);
			
			break;
		}
		case MSG_RATS_SERVER_STOP:
		{
			DEBUG("RATS: Received MSG_RATS_SERVER_STOP from %d\n", msg->saddr);
			//If node has minimum period, then go to validation protocol
			if(msg->saddr == s->ts_packet.min_period_node_id)
			{
				DEBUG("RATS: Going to validation protocol\n");
				s->validation_timer_counter = 1;
				s->validation_timer_retransmissions = BROADCAST_VALIDATION_RETRANSMISSIONS;
				s->validation_node_id = ker_id();
			}

			break;
		}	
		case MSG_TIMER_TIMEOUT:
		{
			switch(p->byte)
			{
				case TRANSMIT_TIMER:
				{
					if( (--(s->transmit_timer_counter)) == 0)
					{
						DEBUG("RATS: Broadcasting MSG_TIMESTAMP packet\n");
						LED_DBG(LED_GREEN_TOGGLE);
						post_net(s->pid, s->pid, MSG_TIMESTAMP, sizeof(ts_packet_t), &s->ts_packet, 0, BCAST_ADDRESS);
						
						#ifdef UART_DEBUG
						post_uart(s->pid, s->pid, UART_TIMESTAMP, sizeof(ts_packet_t), &s->ts_packet, 0, BCAST_ADDRESS);
						#endif //UART_DEBUG
						
						s->transmit_timer_counter = (uint16_t)(s->ts_packet.transmission_period / MIN_SAMPLING_PERIOD);
					}
					break;	
				}
				case VALIDATION_TIMER:
				{
					if( (--(s->validation_timer_counter)) == 0)
					{
						s->validation_timer_counter = 1;
						//Send up to MSG_PERIOD_REQUEST packets (UNICAST_VALIDATION_RETRANSMISSIONS times) to node with minimum period.
						//If the node doesn't respond until then, then broadcast BROADCAST_VALIDATION_RETRANSMISSIONS times
						//After the transmitting BROADCAST_VALIDATION_RETRANSMISSIONS packets, use the minimum period that
						//was sent during that interval
						if( s->validation_timer_retransmissions > BROADCAST_VALIDATION_RETRANSMISSIONS )
						{
							--s->validation_timer_retransmissions;							
							DEBUG("RATS: Transmitting MSG_PERIOD_REQUEST (retries left = %d) to node %d\n", s->validation_timer_retransmissions, s->ts_packet.min_period_node_id);
							post_net(s->pid, s->pid, MSG_PERIOD_REQUEST, 0, NULL, 0, s->ts_packet.min_period_node_id);
							
							#ifdef UART_DEBUG
							post_uart(s->pid, s->pid, UART_PERIOD_REQUEST, 0, NULL, 0, s->ts_packet.min_period_node_id);
							#endif //UART_DEBUG
						}
						else if( s->validation_timer_retransmissions > 0)
						{
							--s->validation_timer_retransmissions;							
							DEBUG("RATS: Broadcasting MSG_PERIOD_REQUEST (retries left = %d)\n", s->validation_timer_retransmissions);
							//Invalidate node with minimum period
							s->validation_node_id = ker_id();
							post_net(s->pid, s->pid, MSG_PERIOD_REQUEST, 0, NULL, 0, BCAST_ADDRESS);
							
							#ifdef UART_DEBUG
							post_uart(s->pid, s->pid, UART_PERIOD_REQUEST, 0, NULL, 0, BCAST_ADDRESS);
							#endif //UART_DEBUG
						}
						else //s->validation_timer_retransmissions == 0
						{
							sys_timer_stop(TRANSMIT_TIMER);
							sys_timer_stop(VALIDATION_TIMER);
							
							//Restart normal procedure only if there was a reply
							if(ker_id() != s->validation_node_id)
							{
								DEBUG("RATS: Setting node %d as the one with min period (%d)\n", 
								s->validation_node_id, s->validation_period);
								s->ts_packet.min_period_node_id = s->validation_node_id;
								s->ts_packet.transmission_period = s->validation_period;
								s->transmit_timer_counter = s->ts_packet.transmission_period/INITIAL_TRANSMISSION_PERIOD;
								s->validation_timer_counter = s->transmit_timer_counter + 4;
								s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS;
								sys_timer_start(TRANSMIT_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT);
								sys_timer_start(VALIDATION_TIMER, MIN_SAMPLING_PERIOD*1024, TIMER_REPEAT);
							}
							else
							{
								DEBUG("RATS: Validation timer expired, without receiving any packets\n");
								sys_timer_stop(TRANSMIT_TIMER);
								sys_timer_stop(VALIDATION_TIMER);								
							}							
						}
					}
					break;
				}
				case PANIC_TIMER:
				{
					//There is a fixed number of retransmissions. If the corresponding counter
					//reaches zero, then the child is removed from the list
					
					/* Select node at head of list */
					timesync_t * ts_list_ptr = s->ts_list;
					timesync_t * ts_delete_list_ptr;
					timesync_t * ts_previous_list_ptr = s->ts_list;

					/* Loop until we've reached the end of the list */
					while( ts_list_ptr != NULL )
					{
						if(--ts_list_ptr->panic_timer_counter == 0)
						{
							if(ts_list_ptr->panic_timer_retransmissions > 0)
							{
								//Transmit the packet
								--ts_list_ptr->panic_timer_retransmissions;								
								DEBUG("RATS: Sending panic packet to node %d (retries=%d)\n", ts_list_ptr->node_id, ts_list_ptr->panic_timer_retransmissions);
								post_net(s->pid, s->pid, MSG_PANIC, 0, NULL, 0, ts_list_ptr->node_id);
								
								//The retransmission period should be INITIAL_TRANSMISSION_PERIOD 
								ts_list_ptr->panic_timer_counter = 1; 
							}
							else
							{
								DEBUG("RATS: Removing node %d from list of parents\n", ts_list_ptr->node_id);
								/* Found the item to be deleted,
	     		 				re-link the list around it */
								if( ts_list_ptr == s->ts_list )
									/* We're deleting the head */
									s->ts_list = ts_list_ptr->next;
								else
									ts_previous_list_ptr->next = ts_list_ptr->next;
	
								ts_delete_list_ptr = ts_list_ptr;
								ts_list_ptr = ts_list_ptr->next;
				
								/* Free the node */
								sys_free( ts_delete_list_ptr );
								continue;
							}
						}						
						ts_previous_list_ptr = ts_list_ptr;
						ts_list_ptr = ts_list_ptr->next;						
					}
					
					//If the parent list is empty, then we're stopping the panic timer
					if(s->ts_list == NULL)
					{
						DEBUG("RATS: Parent list is empty. Stopping panic timer\n");
						#ifdef USE_PANIC_PACKETS
						sys_timer_stop(PANIC_TIMER);
						#endif //USE_PANIC_PACKETS
					}
					
					break;
				}
				default:
					break;
			}
			return SOS_OK;
		}
		case MSG_PERIOD_CHANGE:
		{
			uint16_t temp_transmission_period;
			DEBUG("RATS: Received packet for period change from %d\n", msg->saddr);
			LED_DBG(LED_YELLOW_TOGGLE);
			if((msg->data == NULL) || (msg->len != sizeof(uint16_t)) )
			{
				DEBUG("RATS: Invalid parameters in MSG_PERIOD_CHANGE\n");
				break;
			}
			
			temp_transmission_period = (* (uint16_t*)(msg->data));

			//Change period if:
			//a)received period is smaller than period in use
			//b)node that sent period is the one that has the current smallest period
			//c)I am currently using myself as the node with the smallest period (used in the beginning and in transitive modes)
			if((temp_transmission_period < s->ts_packet.transmission_period) 
				|| (s->ts_packet.min_period_node_id == msg->saddr) 
				|| (s->ts_packet.min_period_node_id == ker_id()) )
			{
				DEBUG("RATS: Changing period (new_period=%d new_node=%d). Sending to UART\n", temp_transmission_period, msg->saddr);
				sys_timer_stop(TRANSMIT_TIMER);
			    sys_timer_stop(VALIDATION_TIMER);
				
				#ifdef UART_DEBUG
				period_packet_t * period_packet_ptr = sys_malloc(sizeof(period_packet_t));
				period_packet_ptr->saddr = msg->saddr;
				period_packet_ptr->old_period = s->ts_packet.transmission_period;
				period_packet_ptr->new_period = temp_transmission_period;
				post_uart(s->pid, s->pid, UART_PERIOD_CHANGE, sizeof(period_packet_t), period_packet_ptr, SOS_MSG_RELEASE, UART_ADDRESS);
				#endif //UART_DEBUG
				
				s->ts_packet.transmission_period = temp_transmission_period;
				s->ts_packet.min_period_node_id = msg->saddr;
				s->transmit_timer_counter = (uint16_t)(s->ts_packet.transmission_period / MIN_SAMPLING_PERIOD);
				s->validation_timer_counter = s->transmit_timer_counter + 4;
				s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS;
				sys_timer_start(TRANSMIT_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT);
				sys_timer_start(VALIDATION_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT);
			}
			return SOS_OK;	
		}
		case MSG_TIMESTAMP:
		{
			ts_packet_t *ts_packet_ptr = (ts_packet_t *)msg->data;
			DEBUG("RATS: MSG_TIMESTAMP with type = %d\n", ts_packet_ptr->type);
			if(ts_packet_ptr->type == NORMAL_PACKET)
			{
				DEBUG("RATS: Receiving timestamp data from node %d\n", msg->saddr);
				if( add_values(s, msg) == TRUE)
				{
					LED_DBG(LED_GREEN_TOGGLE);
					DEBUG("RATS: Accessed internal structure\n");
				}
				else
				{
					DEBUG("RATS: Discarding MSG_TIMESTAMP from node %d\n", msg->saddr);
				}
			}
			else // TEST_PACKET
			{
				if(ker_id() == ROOT_NODE)
				{
					DEBUG("RATS: Receiving test data from node %d. Sending to UART\n", msg->saddr);
					#ifdef UART_DEBUG
					ext_packet_t * ext_packet_ptr = (ext_packet_t *)msg->data;
					debug_packet_t * debug_packet_ptr = (debug_packet_t *)sys_malloc(sizeof(debug_packet_t));
					debug_packet_ptr->time[0] = ticks_to_msec_float(ext_packet_ptr->time[0]);
					debug_packet_ptr->time[1] = ticks_to_msec_float(ext_packet_ptr->time[1]);
					debug_packet_ptr->node_id = ker_id();
					debug_packet_ptr->int_parent_time = ext_packet_ptr->time[1];
					post_uart(s->pid, s->pid, UART_FORWARD_EXT, sizeof(debug_packet_t), debug_packet_ptr, SOS_MSG_RELEASE, UART_ADDRESS);
					#endif //UART_DEBUG
				}
				else
				{
					DEBUG("RATS: Receiving test data from node %d. Sending to parent\n", msg->saddr);
					#ifdef UART_DEBUG
					ext_packet_t * ext_packet_ptr = (ext_packet_t *)msg->data;
					uint32_t parent_time = convert_from_mine_to_parent_time(ext_packet_ptr->time[1], ROOT_NODE);
					
					//Break if the parent is not found in the timestamping list
					if(parent_time == 0)
					{
						break;
					}
					
					debug_packet_t * debug_packet_ptr = (debug_packet_t *)sys_malloc(sizeof(debug_packet_t));
					debug_packet_ptr->time[0] = ticks_to_msec_float(ext_packet_ptr->time[0]);
					debug_packet_ptr->time[1] = ticks_to_msec_float(parent_time);
					debug_packet_ptr->int_parent_time = parent_time;
					debug_packet_ptr->node_id = ker_id();					
					post_uart(s->pid, s->pid, UART_FORWARD_EXT, sizeof(debug_packet_t), debug_packet_ptr, SOS_MSG_RELEASE, UART_ADDRESS);
					#endif //UART_DEBUG
				}
			}
			break;
		}
		case MSG_PERIOD_REQUEST:
		{
			DEBUG("RATS: Received MSG_PERIOD_REQUEST packet from node %d\n", msg->saddr);
			timesync_t * temp_ts_ptr = get_timesync_ptr(s, msg->saddr);
			if(temp_ts_ptr == NULL)
			{
				DEBUG("RATS: Discarding MSG_PERIOD_REQUEST\n");
				break;
			}

			uint16_t *sampling_period = (uint16_t *)sys_malloc(sizeof(uint16_t));
			if(sampling_period != NULL)
			{
				*sampling_period = temp_ts_ptr->sampling_period;
				DEBUG("RATS: Sending MSG_PERIOD_REPLY packet (period=%d) to node %d\n", *sampling_period, msg->saddr);
				post_net(s->pid, s->pid, MSG_PERIOD_REPLY, sizeof(uint16_t), sampling_period, SOS_MSG_RELEASE, msg->saddr);
			}
			break;
		}
		case MSG_PERIOD_REPLY:
		{
			uint16_t transmission_period;
			DEBUG("RATS: Received MSG_PERIOD_REPLY packet from node %d\n", msg->saddr);
			memcpy(&transmission_period, &msg->data[0], sizeof(transmission_period));
			s->validation_timer_counter = s->transmit_timer_counter + 4;
			s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS;
			if((transmission_period < s->validation_period) || (s->validation_node_id == ker_id() ) )
			{
				DEBUG("RATS: Changing VALIDATION period (new_period=%d new_node=%d)\n", transmission_period, msg->saddr);
				s->validation_period = transmission_period;
				s->validation_node_id = msg->saddr;
			}
			break;
		}
		case MSG_PANIC:
		{
			//Transmit MSG_TIMESTAMP, restart timer, recalculate value for transmit_timer_counter
			sys_timer_stop(TRANSMIT_TIMER);
			sys_timer_stop(VALIDATION_TIMER);
			
			#ifdef UART_DEBUG
			uint16_t *data = (uint16_t *)sys_malloc(sizeof(uint16_t));
			*data = msg->saddr;
			post_uart(s->pid, s->pid, UART_PANIC, sizeof(uint16_t), data, SOS_MSG_RELEASE, UART_ADDRESS);
			#endif //UART_DEBUG
			
			post_net(s->pid, s->pid, MSG_TIMESTAMP, sizeof(ts_packet_t), &s->ts_packet, 0, BCAST_ADDRESS);
			s->transmit_timer_counter = (uint16_t)(s->ts_packet.transmission_period / MIN_SAMPLING_PERIOD);
			s->validation_timer_counter = s->transmit_timer_counter + 4;
			s->validation_timer_retransmissions = TOTAL_VALIDATION_RETRANSMISSIONS;
			sys_timer_start(TRANSMIT_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT);
			sys_timer_start(VALIDATION_TIMER, INITIAL_TRANSMISSION_PERIOD*1024, TIMER_REPEAT);
			break;
		}
		case MSG_INVALIDATE_ENTRY:
		{
			DEBUG("RATS: Received invalidation message from node %d\n", msg->saddr);
			timesync_t * temp_ts_ptr = get_timesync_ptr(s, msg->saddr);
			if(temp_ts_ptr == NULL)
			{
				DEBUG("RATS: Discarding MSG_INVALIDATE_ENTRY\n");
				break;
			}
			
			DEBUG("RATS: Invalidation entry for node %d\n", msg->saddr);
			temp_ts_ptr->packet_count = 0;
			temp_ts_ptr->a = 0;
			temp_ts_ptr->b = 0;		
			temp_ts_ptr->sampling_period = INITIAL_TRANSMISSION_PERIOD;
			temp_ts_ptr->window_size = (uint8_t)BUFFER_SIZE;
			temp_ts_ptr->panic_timer_counter = 5; //(s->ts_list->sampling_period / INITIAL_TRANSMISSION_PERIOD) + 4;
			temp_ts_ptr->panic_timer_retransmissions = PANIC_TIMER_RETRANSMISSIONS;			
			memset(temp_ts_ptr->timestamps, 0, BUFFER_SIZE*sizeof(uint32_t));
			memset(temp_ts_ptr->my_time, 0, BUFFER_SIZE*sizeof(uint32_t));


			//Notify node to start procedure from beginning
			post_net(s->pid, s->pid, MSG_RATS_SERVER_START, 0, NULL, 0, msg->saddr);
			break;
		}
        case MSG_FINAL:
        {
			sys_timer_stop(TRANSMIT_TIMER);
			sys_timer_stop(VALIDATION_TIMER);
			
			#ifdef USE_PANIC_PACKETS
			sys_timer_stop(PANIC_TIMER);
			#endif //USE_PANIC_PACKETS
			
			return SOS_OK;
        }
        default:
			return -EINVAL;
	}

    /**
     * Return SOS_OK for those handlers that have successfully been handled.
     */
    return SOS_OK;
}
Пример #27
0
	int main(int argc, char* argv[])
	{

	int    thr_id[NUM_HANDLER_THREADS];      /* thread IDs            */
	pthread_t p_threads[NUM_HANDLER_THREADS];    /* thread's structures   */

	int num;
	char msg[MAXDATASIZE];

	quit = 0;
	/* create the request-handling threads */
	for (int i=0; i<NUM_HANDLER_THREADS; i++) {
	   thr_id[i] = i;
	   pthread_create(&p_threads[i], NULL, handle_requests_loop, (void*)&thr_id[i]);
	   }

	/* Create UDP socket  */
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
	   /* handle exception */
	   perror("Creating socket failed.");
	   exit(1);
	}

	int opt = SO_REUSEADDR;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	bzero(&server,sizeof(server));
	server.sin_family=AF_INET; 
	server.sin_port=htons(PORT); 
	server.sin_addr.s_addr = htonl (INADDR_ANY); 
	if (bind(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) { 
	   /* handle exception */
	   perror("Bind error.");
	   exit(1); 
	   }    

	sin_size=sizeof(struct sockaddr_in); 
	while (1) 
	{

	   num = recvfrom(sockfd,msg,MAXDATASIZE,0,(struct sockaddr *)&client,&sin_size);                                             
	   if (num < 0){
	      perror("recvfrom error\n"); 
	      exit(1); 
	      } 

	   msg[num] = '\0';
	   printf("You got a message (%s%) from %s\n",msg,inet_ntoa(client.sin_addr) ); 
	   add_request(msg, &list_mutex, &got_request);
	   if (!strcmp(msg,"quit")) {
	      /* notify our threads we're done . */
	      int rc;
	      rc = pthread_mutex_lock(&request_mutex);
	      quit = 1;
	      rc = pthread_cond_broadcast(&got_request);
	      rc = pthread_mutex_unlock(&request_mutex);

	      /* wait until other thread quit */
	      for (int i=0; i<NUM_HANDLER_THREADS; i++) {
	         pthread_join(p_threads[i], NULL);
	         }
	      break;
	      } 
	}
	close(sockfd);   /* close listenfd */         
	return 0;
	}