void on_accept(int fd, short ev, void *arg) {
	int client_fd;
	struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);
	workqueue_t *workqueue = (workqueue_t *)arg;
	client_t *client;
	job_t *job;

	client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
	if (client_fd < 0) {
		warn("accept failed");
		return;
	}

	if (setnonblock(client_fd) < 0) {
		warn("failed to set client socket to non-blocking");
		close(client_fd);
		return;
	}

	if ((client = malloc(sizeof(*client))) == NULL) {
		warn("failed to allocate memory for client state");
		close(client_fd);
		return;
	}
	memset(client, 0, sizeof(*client));
	client->fd = client_fd;

	if ((client->output_buffer = evbuffer_new()) == NULL) {
		warn("client output buffer allocation failed");
		closeAndFreeClient(client);
		return;
	}

	if ((client->evbase = event_base_new()) == NULL) {
		warn("client event_base creation failed");
		closeAndFreeClient(client);
		return;
	}

	if ((client->buf_ev = bufferevent_new(client_fd, buffered_on_read, buffered_on_write, buffered_on_error, client)) == NULL) {
		warn("client bufferevent creation failed");
		closeAndFreeClient(client);
		return;
	}
	bufferevent_base_set(client->evbase, client->buf_ev);
	bufferevent_enable(client->buf_ev, EV_READ);

	if ((job = malloc(sizeof(*job))) == NULL) {
		warn("failed to allocate memory for job state");
		closeAndFreeClient(client);
		return;
	}
	job->job_function = server_job_function;
	job->user_data = client;

	workqueue_add_job(workqueue, job);
}
示例#2
0
文件: threadsay.c 项目: wadee/go_proj
static void maxconns_handler(const int fd, const short which, void *arg) {
    struct timeval t = {.tv_sec = 0, .tv_usec = 10000};

    if (fd == -42 || allow_new_conns == false) {
        /* reschedule in 10ms if we need to keep polling */
        evtimer_set(&maxconnsevent, maxconns_handler, 0);
        event_base_set(main_base, &maxconnsevent);
        evtimer_add(&maxconnsevent, &t);
    } else {
        evtimer_del(&maxconnsevent);
        accept_new_conns(true);
    }
}

static bool update_event(conn *c, const int new_flags) {
    assert(c != NULL);

    
    if (c->ev_flags == new_flags)
        return true;
    pthread_t tid = pthread_self();
    if (tid == dispatcher_thread.thread_id)
    {
        struct event_base *base = c->event.ev_base;
        if (event_del(&c->event) == -1) return false;    
        event_set(&c->event, c->sfd, new_flags, master_event_handler, (void *)c);
        event_base_set(base, &c->event);
        c->ev_flags = new_flags;
        if (event_add(&c->event, 0) == -1) return false;
        return true;
    }else{
        struct event_base *base = bufferevent_get_base(c->buf_ev);
        bufferevent_free(c->buf_ev);
        c->buf_ev = bufferevent_new(c->sfd, event_handler, buf_write_callback, buf_error_callback, (void * )c);
        bufferevent_base_set(base, c->buf_ev);
        
        c->ev_flags = new_flags;
        if (bufferevent_enable(c->buf_ev, new_flags) == -1) return false;
        return true;
    }    
    //这个也得改成bufferevent的形式
/*

    event_set(&c->event, c->sfd, new_flags, event_handler, (void *)c);
    event_base_set(base, &c->event);
    event_add(&c->event, 0);


    c->buf_ev = bufferevent_new(c->sfd, event_handler, event_handler, NULL, (void * )c);
    bufferevent_base_set(base, c->buf_ev);
    bufferevent_enable(c->buf_ev, new_flags);

    c->ev_flags = new_flags;
    if (event_add(&c->event, 0) == -1) return false;
    return true;
*/
}
示例#3
0
文件: threadsay.c 项目: wadee/go_proj
conn *conn_new(const int sfd, enum conn_states init_state,
                const int event_flags,
                const int read_buffer_size, enum network_transport transport,
                struct event_base *base) {
    /*此函数需要做的事情
        1.新建一个conn结构,加入到connQ
        2.为此链接(文件描述符),注册一个event_handler
        3.event_handler进行状态的处理,不同状态不同的处理方式,master,slave共用此方法。
    */
    conn * new_c;
    new_c = conns[sfd];
    if (NULL == new_c)
    {
        if ( !(new_c = (conn *)calloc(1, sizeof(conn))) )
        {
            perror("alloc conn fail");
            exit(1);
        }

        new_c->sfd = sfd;
        conns[sfd] = new_c;
    }

    new_c->state = init_state;
    //以上是连接的初始化,接下来是连接的事件注册
    
     pthread_t tid = pthread_self();
     if (tid == dispatcher_thread.thread_id)
     {
        event_set(&new_c->event, sfd, event_flags, master_event_handler, (void*)new_c);
        event_base_set(base, &new_c->event);
        event_add(&new_c->event, 0);
     }else{
        new_c->buf_ev = bufferevent_new(sfd, event_handler, event_handler, buf_error_callback, (void *)new_c);
        bufferevent_base_set(base, new_c->buf_ev);
        bufferevent_enable(new_c->buf_ev, event_flags);
     }
     
     
     /*
     想着想着还是决定改成用bufferevent。
     因为master线程与slave用的是同一个函数来做处理event_handler -> drive_machine,
     所以master线程的accept也需要改为用bufferevent,而且event_handler以及drive_machine也得改
     还有struct conn的event也得改呀,得改成bufferevent类型呢

     */

     /*
    new_c->buf_ev = bufferevent_new(sfd, event_handler, event_handler, buf_error_callback, (void *)new_c);
    bufferevent_base_set(base, new_c->buf_ev);
    bufferevent_enable(new_c->buf_ev, event_flags);
    */
    
    return new_c;
}
示例#4
0
static void
http_base_test(void)
{
	struct bufferevent *bev;
	int fd;
	const char *http_request;
	short port = -1;

	test_ok = 0;
	fprintf(stdout, "Testing HTTP Server Event Base: ");

	base = event_init();

	/* 
	 * create another bogus base - which is being used by all subsequen
	 * tests - yuck!
	 */
	event_init();

	http = http_setup(&port, base);
	
	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, http_readcb, http_writecb,
	    http_errorcb, NULL);
	bufferevent_base_set(base, bev);

	http_request =
	    "GET /test HTTP/1.1\r\n"
	    "Host: somehost\r\n"
	    "Connection: close\r\n"
	    "\r\n";

	bufferevent_write(bev, http_request, strlen(http_request));
	
	event_base_dispatch(base);

	bufferevent_free(bev);
	EVUTIL_CLOSESOCKET(fd);

	evhttp_free(http);

	event_base_free(base);
	base = NULL;
	
	if (test_ok != 2) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}
	
	fprintf(stdout, "OK\n");
}
示例#5
0
/*
 * Create a new bufferevent for a socket and register it with the provided
 * base.  Note that options is always ignored, so programs using this backward
 * compatibility layer cannot rely on it.
 */
struct bufferevent *
bufferevent_socket_new(struct event_base *base, evutil_socket_t fd,
                       int options UNUSED)
{
    struct bufferevent *bev;

    bev = bufferevent_new(fd, NULL, NULL, NULL, NULL);
    if (bufferevent_base_set(base, bev) < 0) {
        bufferevent_free(bev);
        return NULL;
    }
    return bev;
}
示例#6
0
文件: client.c 项目: iksaif/sockslink
Client *client_new(SocksLink *sl, int fd, struct sockaddr_storage *addr,
		   socklen_t addrlen)
{
  Client *cl = calloc(sizeof (*cl), 1);
  struct bufferevent *bev;

  INIT_LIST_HEAD(&cl->next);
  INIT_LIST_HEAD(&cl->next_auth);

  if (!cl)
    return NULL;

  bev = bufferevent_new(fd, NULL, NULL, NULL, NULL);
  if (!bev) {
    free(cl);
    return NULL;
  }

  bufferevent_base_set(sl->base, bev);

  cl->client_method = AUTH_METHOD_INVALID;
  cl->server_method = AUTH_METHOD_INVALID;
  cl->parent = sl;
  cl->client.bufev = bev;
  cl->client.fd = fd;
  cl->client.addr = *addr;
  cl->client.addrlen = addrlen;
  cl->server.fd = -1;

  list_add(&cl->next, &sl->clients);

  if (sl->pipe) {
    client_connect_server(cl);
  } else {
    bufferevent_setcb(bev, on_client_read_init, on_client_write, on_client_event, cl);
    bufferevent_settimeout(bev, SOCKS5_AUTH_TIMEOUT, SOCKS5_AUTH_TIMEOUT);
    bufferevent_enable(bev, EV_READ|EV_WRITE);
  }

  return cl;
}
void SocketListen::OnAccept(int fd)
{
	struct sockaddr_in sin;
    socklen_t len = sizeof(sin);
	int socket_fd = accept(fd, (struct sockaddr*)&sin, &len);
	string ip = inet_ntoa(sin.sin_addr);
	//std::cout << __func__ <<" "<<ip<<" "<<"port: "<<sin.sin_port <<" socket_fd = "<<socket_fd<< std::endl;
	if (socket_fd == INVALID_SOCKET || socket_fd == SOCKET_ERROR)
	{
		std::cout << __func__<< " listen error errno = "<< errno << std::endl;
		return ;
	}
	evutil_make_socket_nonblocking(socket_fd);

	SocketStream* ss = SocketStreamMgr::Instance().Add(sin.sin_addr.s_addr, queue_);
	if (!ss)
		return ;
	ss->SetIsShortConnect(is_short_connnect_);
	ss->SetSocketFd(socket_fd);
	ss->buffer_event_ = bufferevent_new(socket_fd, SocketStream::OnReadCb, SocketStream::OnWriteCb, SocketStream::OnErrorCb,ss);
	bufferevent_base_set(base_, ss->buffer_event_);
	bufferevent_enable(ss->buffer_event_, EV_READ | EV_WRITE);
	ss->Connected();
}
示例#8
0
/**
* This function will be called by libevent when there is a connection
* ready to be accepted.
*/
void on_accept(int fd, short ev, void *arg) {
	int client_fd;
	struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);
	workqueue_t *workqueue = (workqueue_t *)arg;
	client_t *client;
	job_t *job;

	client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
	if (client_fd < 0) {
		warn("accept failed");
		return;
	}
	printf("Run accept fd:%d\n", fd);
	/* Set the client socket to non-blocking mode. */
	if (setnonblock(client_fd) < 0) {
		;
		warn("failed to set client socket to non-blocking");
		close(client_fd);
		return;
	}

	/* Create a client object. */
	if ((client = (client_t *)malloc(sizeof(*client))) == NULL) {
		warn("failed to allocate memory for client state");
		close(client_fd);
		return;
	}
	memset(client, 0, sizeof(*client));
	client->fd = client_fd;

	/* Add any custom code anywhere from here to the end of this function
	* to initialize your application-specific attributes in the client struct. */

	if ((client->output_buffer = evbuffer_new()) == NULL) {
		warn("client output buffer allocation failed");
		closeAndFreeClient(client);
		return;
	}

	if ((client->evbase = event_base_new()) == NULL) {
		warn("client event_base creation failed");
		closeAndFreeClient(client);
		return;
	}

	/* Create the buffered event.
	*
	* The first argument is the file descriptor that will trigger
	* the events, in this case the clients socket.
	*
	* The second argument is the callback that will be called
	* when data has been read from the socket and is available to
	* the application.
	*
	* The third argument is a callback to a function that will be
	* called when the write buffer has reached a low watermark.
	* That usually means that when the write buffer is 0 length,
	* this callback will be called.  It must be defined, but you
	* don't actually have to do anything in this callback.
	*
	* The fourth argument is a callback that will be called when
	* there is a socket error.  This is where you will detect
	* that the client disconnected or other socket errors.
	*
	* The fifth and final argument is to store an argument in
	* that will be passed to the callbacks.  We store the client
	* object here.
	*/
	if ((client->buf_ev = bufferevent_new(client_fd, buffered_on_read, buffered_on_write, buffered_on_error, client)) == NULL) {
		warn("client bufferevent creation failed");
		closeAndFreeClient(client);
		return;
	}
	bufferevent_base_set(client->evbase, client->buf_ev);

	bufferevent_settimeout(client->buf_ev, SOCKET_READ_TIMEOUT_SECONDS, SOCKET_WRITE_TIMEOUT_SECONDS);

	/* We have to enable it before our callbacks will be
	* called. */
	bufferevent_enable(client->buf_ev, EV_READ);

	/* Create a job object and add it to the work queue. */
	if ((job = (job_t *)malloc(sizeof(*job))) == NULL) {
		warn("failed to allocate memory for job state");
		closeAndFreeClient(client);
		return;
	}
	job->job_function = server_job_function;
	job->user_data = client;

	workqueue_add_job(workqueue, job);
}