コード例 #1
0
ファイル: fork.c プロジェクト: hsaransa/std2
static void read_cb(int fd, int mask, void* user)
{
    int fork_id = (int)user;
    fork_state* fs = get_fork(fork_id);
    assert(fd == fs->to_host_fd[0]);

    fs->has_yielded_reader = 0;

    if (mask & STD2_CALLBACK_ABORT)
    {
        assert(!"abort not implemented");
        abort();
        return;
    }

    buffer_reserve(&fs->in_buffer, 1024);
    int closed = read_buffer_append(fd, &fs->in_buffer, 1);

    /* If fd was closed, abort all returns. */

    if (closed)
    {
        request* req;
        for (req = fs->first_request; req; req = req->next)
            std2_abort_return(req->return_id);
        return;
    }

    /* fd wasn't closed so yield new read callback. */
    yield_callbacks(fork_id);

    if (!fs->return_processed)
        return;

    fprintf(stderr, "NAH\n");

    if (buffer_avail(&fs->in_buffer) < 8)
        return;

    int ret_id   = *(std2_int32*)buffer_cursor(&fs->in_buffer);
    int ret_size = *((std2_int32*)buffer_cursor(&fs->in_buffer) + 1);

    if (buffer_avail(&fs->in_buffer) < 8 + ret_size)
        return;

    fprintf(stderr, "std2: got return from fork, id %d, size %d\n", ret_id, ret_size);
    request* req;
    for (req = fs->first_request; req; req = req->next)
        if (req->id == ret_id)
        {
            fs->return_processed = 0;
            std2_continue_return(req->return_id, return_func, req);
            return;
        }

    fprintf(stderr, "std2: bad request id\n");
}
コード例 #2
0
ファイル: brutedet.c プロジェクト: gvberg/brutedet
int
main(int argc, char ** argv)
{
	struct termios tio;
	struct buffer * data;
	struct pollfd pfd;
	size_t off;
	char line[MAX_LINELEN], *p, * cmd;
	int ret, fd, c;
	uint32_t capacity, nfuncs, counts_per_func, size, i, j, index, min;
	uint32_t * bitmaps[NR_BITMAPS], * hashes;
	uint32_t bitmap_diffs[NR_BITMAPS] = {10, 60, 600};
	uint32_t bitmap_max[NR_BITMAPS] = {2, 10, 50};
	struct taia timestamps[NR_BITMAPS], now, diff;
	double error_rate;


	while ((c = getopt(argc, argv, "c:e:h")) != -1) {
		switch (c) {
		case 'h':
			usage(argc > 0 ? argv[0] : "(unknown)");
			break;
		case 'c':
			capacity = atoi(optarg);
			break;
		case 'e':
			error_rate = atof(optarg);
			break;
		}
	}

	if (argc-optind != NR_BITMAPS+1) {
		fprintf(stderr, "not enough (or too many) arguments supplied\n\n");
		usage(argc > 0 ? argv[0] : "(unknown)");
	}

	/* get the tresholds from the command line */
	for (i=0;i<NR_BITMAPS;i++) {
		bitmap_diffs[i] = atoi(argv[optind+i]);
		printf("%i\n", bitmap_diffs[i]);
	}

	/* get the command which will be executed */
	cmd = argv[optind+3];

	/* calculate the bloom filter parameters */
	capacity = CAPACITY;
	error_rate = ERROR_RATE;
	nfuncs = (int)ceil(log(1/error_rate) / log(2));
	counts_per_func = (int) ceil(capacity * fabs(log(error_rate))
		/(nfuncs * pow(log(2), 2)));
	size = nfuncs * counts_per_func * sizeof(uint32_t);

	debug("nfuncs: %u, counts_per_func: %u, size: %u, bits: %lu\n",
		nfuncs, counts_per_func, size, size/sizeof(uint32_t));

	/* allocate all the bitmaps necessary and set timestamps */
	taia_now(&now);
	for (i=0;i<NR_BITMAPS;i++) {
		bitmaps[i] = xmalloc(size);
		memcpy(&(timestamps[i]), &now, sizeof(struct taia));
	}

	/* allocate hash structure used to calculate bitmap indices */
	hashes = xmalloc(nfuncs * sizeof(uint32_t));

	/* turn of line buffering */
	tcgetattr(STDIN_FILENO, &tio);
	tio=tio;
	tio.c_lflag &=(~ICANON);
	tcsetattr(STDIN_FILENO,TCSANOW, &tio);

	/* prepare poll */
	fd = STDIN_FILENO;
	pfd.fd = fd;
	pfd.events = POLLIN;
	data = buffer_new();

	/* event loop */
	while (1) {
		/* timeout every second */
		ret = poll(&pfd, 1, 1000);
		if (ret < 0) pfatal("poll");

		if (pfd.revents == POLLIN) {
			buffer_fd_append(data, fd, fd_ravail(fd));

			ret = buffer_findchar(data, '\n', &off);	
		nextline:	
			if (ret < 0) {
				if (buffer_avail(data)>=MAX_LINELEN) {
					fatal("line too long");
				}
				continue;
			}
			else if (off >= MAX_LINELEN-1) {
				fatal("line too long");
			}
			buffer_consume(data, line, off+1);	
			buffer_reset(data);
			line[off] = 0;
		
			/* strip whitespace between id and data and
			 * rejoin the datasuch that it's only
			 * separated by a space */
			p = line;
			while (*p) {
				if (*p == ' ' || *p == '\t') {
					*p = 0;
					p++;
					break;
				}
				p++;
			}
			while (*p == ' ' || *p == '\t') p++;
			if (!strlen(line) || p == line+off)
				fatal("invalid line");

			/* reset the data so that the id and the data
				are separated by just only one space */
			memmove(line+strlen(line)+1, p, strlen(p));
			*(line+strlen(line)) = 0;
			*(line+strlen(line)+1+strlen(p))=0;

			/* calculate the hashes */
			hash_func(line, strlen(line), hashes,
				nfuncs, counts_per_func);

			/* loop over the bitmaps and see if for any of the
			 * maps the maximum limits were reached */
			for (j=0;j<NR_BITMAPS;j++) {
				min = UINT32_MAX;
				for (i=0;i<nfuncs;i++) {
					off = i * counts_per_func;
					index = hashes[i] + off;	
					bitmaps[j][index] += 1;	
					if (bitmaps[j][index] < min) {
						min = bitmaps[j][index];
					}
				}
				if (min > bitmap_max[j]) {
					debug("treshold reached for %s\n",
						line);
					exec_cmd(cmd, line);
				}
			}
	
			ret = buffer_findchar(data, '\n', &off);	
			if (ret >= 0) goto nextline;
		}

		/* reset the bitmaps if they've passed the time treshold */
		taia_now(&now);
		for (i=0;i<NR_BITMAPS;i++) {
			taia_diff(&timestamps[i], &now, &diff);
			if (diff.sec.x >= bitmap_diffs[i]) {
				memcpy(&(timestamps[i]), &now,
					sizeof(struct taia));
				memset(bitmaps[i], 0, size);
			}
		}	
	}
}
コード例 #3
0
ファイル: fork.c プロジェクト: hsaransa/std2
void std2_process_request()
{
    fork_state* fs = get_fork(current_fork_id);

    if (read_buffer_append(fs->to_client_fd[0], &fs->in_buffer, 20))
    {
        fprintf(stderr, "std2: child got disconnection\n");
        exit(1);
    }

    int marker = buffer_read_32(&fs->in_buffer);
    int req_id = buffer_read_32(&fs->in_buffer);

    if (marker == 'c')
    {
        int m = buffer_read_32(&fs->in_buffer);
        int f = buffer_read_32(&fs->in_buffer);
        int params_size = buffer_read_32(&fs->in_buffer);

        read_buffer_append(fs->to_client_fd[0], &fs->in_buffer, params_size);

        fprintf(stderr, "call id=%d, %d, %d, %d\n", req_id, m, f, params_size);

        // Construct parameters.

        void* start_ptr = buffer_cursor(&fs->in_buffer);
        void* end_ptr = (char*)buffer_cursor(&fs->in_buffer) + params_size;
        void* p = start_ptr;

        void* args[16];

        int param_count = std2_get_param_count(m, f);
        int i;
        for (i = 0; i < param_count; i++)
        {
            struct std2_param t = std2_get_param_type(m, f, i);
            switch (t.type)
            {
                case STD2_INT32:
                    args[i] = p;
                    p = (char*)p + 4;
                    break;

                case STD2_C_STRING:
                    {
                        int size = *(int*)p;
                        p = (char*)p + 4;
                        args[i] = p;
                        p = (char*)p + size;
                    }
                    break;

                case STD2_INSTANCE:
                    args[i] = *(void**)p;
                    p = (char*)p + sizeof(void*);
                    break;

                default:
                    fprintf(stderr, "std2: (c) unknown type %d\n", t.type);
                    abort();
            }

            assert(p <= end_ptr);
        }

        fs->in_buffer.pos += (char*)p - (char*)start_ptr;

        // Do the call.

        struct std2_param ret_type = std2_get_return_type(m, f);

        buffer_append_32(&fs->out_buffer, req_id); // size will be filled afterwards

        int size_pos = fs->out_buffer.size;
        buffer_append_32(&fs->out_buffer, 0); // size will be filled afterwards

        int ret;

        switch (ret_type.type)
        {
            case STD2_VOID:
                ret = std2_call(0, m, f, 0, args);
                break;

            case STD2_INT32:
                {
                    std2_int32 v;
                    ret = std2_call(0, m, f, &v, args);
                    if (!ret)
                        buffer_append_32(&fs->out_buffer, v);
                }
                break;

            case STD2_C_STRING:
                {
                    const char* v;
                    ret = std2_call(0, m, f, &v, args);
                    if (!ret)
                    {
                        int l = strlen(v) + 1;
                        int n = (l + 3) & ~3;
                        buffer_append_32(&fs->out_buffer, n);
                        buffer_append_data(&fs->out_buffer, v, l);
                        buffer_append_alignment(&fs->out_buffer, 4);
                    }
                }
                break;

            case STD2_INSTANCE:
                {
                    void* v;
                    ret = std2_call(0, m, f, &v, args);
                    if (!ret)
                        buffer_append_data(&fs->out_buffer, &v, sizeof(void*));
                }
                break;

            default:
                fprintf(stderr, "std2: (a) unknown type %d\n", ret_type.type);
                abort();
        }

        if (ret)
        {
            fprintf(stderr, "delayed return\n");
            fs->out_buffer.size -= 8; // req_id and size
            return;
        }

        *(int*)((char*)fs->out_buffer.data + size_pos) =
            fs->out_buffer.size - size_pos - 4;

        while (buffer_avail(&fs->out_buffer))
            write_buffer(fs->to_host_fd[1], &fs->out_buffer);

        fprintf(stderr, "response written\n");

        buffer_compact(&fs->in_buffer);
        buffer_compact(&fs->out_buffer);
    }
    else if (marker == 'u')
    {
        assert(!"todo unrefer");
    }
    else
    {
        fprintf(stderr, "std2: protocol error, bad marker %d\n", marker);
        abort();
    }
}