예제 #1
0
파일: app-2.c 프로젝트: palmtoy/Exercise
void error_cb(struct bufferevent *bev, short event, void *arg)
{
  evutil_socket_t fd = bufferevent_getfd(bev);
  printf("fd = %u, ", fd);
  if (event & BEV_EVENT_TIMEOUT) {
    printf("Timed out\n"); //if bufferevent_set_timeouts() called
  }
  else if (event & BEV_EVENT_EOF) {
    printf("connection closed\n");
  }
  else if (event & BEV_EVENT_ERROR) {
    printf("some other error\n");
  }
  bufferevent_free(bev);
}
예제 #2
0
/* 事件回调函数,连接状态改变时回调的函数 */
void event_cb(struct bufferevent *bev, short events, void *ptr)
{
    struct event_base *tbase = (struct event_base*)ptr;
    if ( events & BEV_EVENT_CONNECTED){
	/* We're connected to server. Ordinarily we'd do
           something here, like start reading or writing. */
        evutil_socket_t fd = bufferevent_getfd(bev);
        set_tcp_no_delay(fd);
	    printf("Server is connected!\n");
    }else { //如果连接不成功的消息,就停止事件循环
    	bufferevent_free(bev);
    	event_base_loopbreak(tbase);
    	printf("Server connect erro!! or The connect have been shutdown: %X\n", events);
    }
}
예제 #3
0
파일: main.cpp 프로젝트: GangXu/websocket
void listencb(struct evconnlistener *listener, evutil_socket_t clisockfd, struct sockaddr *addr, int len, void *ptr) {
	struct event_base *eb = evconnlistener_get_base(listener);
	struct bufferevent *bev = bufferevent_socket_new(eb, clisockfd, BEV_OPT_CLOSE_ON_FREE);
	LOG("a user logined in, socketfd = %d", bufferevent_getfd(bev));

	//create a user
	user_t *user = user_create();
	user->wscon->bev = bev;
	user_vec.push_back(user);
	//ws_conn_setcb(wscon, HANDSHAKE, testfunc, (void*)"haha");
	ws_conn_setcb(user->wscon, FRAME_RECV, frame_recv_cb, user);
	ws_conn_setcb(user->wscon, CLOSE, user_disconnect_cb, user);

	ws_serve_start(user->wscon);
}
예제 #4
0
void read_cb(struct bufferevent*bev, void*arg)//循环读取套接字里的内容;
{
    #define MAX_LINE 256
    char line[MAX_LINE+1]={0};
    QR_HEAD *head;
    QA_HEAD qa_head;
    memset(&qa_head, 0, sizeof(QA_HEAD));
    qa_head.package_len = 232;
    qa_head.package_id = 11;
    HashNode **getinfo;//储存查询结果信息;
    int n;
    int i=0; 
    
    char *buf = malloc(sizeof(QA_HEAD)+4096);
    
    evutil_socket_t fd = bufferevent_getfd(bev);//获取套接字描述符;
    while(n = bufferevent_read(bev, line, MAX_LINE), n>0)//读取套接字中的内容;
    {
        head = (QR_HEAD*)line;
        
        printf("len %d\n", head->package_len);
        printf("id %d\n", head->package_id);
        printf("fd = %u, readline:%s", fd, (char*)(line+sizeof(QR_HEAD)));
        if(head->package_id == 9)//检测是不是reload包,通知重载hash表;
        {
            update_hash_table();//重载hash表内容;
            continue;
        }
        getinfo = hash_table_lookup(line+sizeof(QA_HEAD));//查询hash表;
        if(getinfo == NULL)//如果没有查询到响应的信息,设置包长度为包头长度;
        {
            qa_head.package_len = 8;
            memcpy(buf, &qa_head, sizeof(QA_HEAD));
        }
        else
        {
            i = 0;
            while(getinfo[i])//循环往包里添加查询到的数据;
            {
                memcpy(buf+sizeof(QA_HEAD)+i*sizeof(INFOR), getinfo[i]->infor, sizeof(INFOR));
                i++;
            }
            qa_head.package_len = sizeof(QA_HEAD)+i*sizeof(INFOR);
            memcpy(buf, &qa_head, sizeof(QA_HEAD));
        }
        bufferevent_write(bev, buf, sizeof(QA_HEAD)+4096);//发包;
    }
}
예제 #5
0
void CBareConnection::conn_event(bufferevent* bev, short event, void* ctx)
{
    assert(bev != nullptr);
    assert(ctx != nullptr);
    CBareConnection* data = static_cast<CBareConnection*>(ctx);
    if ((event & BEV_EVENT_CONNECTED) != 0)
        data->OnConnectSuccess(std::move(data->m_bev));
    else {
        evutil_socket_t sock = bufferevent_getfd(bev);
        (void)sock;
        // sock may be BAD_SOCKET here if it wasn't successfully created.
        int error = evutil_socket_geterror(sock);
        data->m_bev.free();
        data->OnConnectFailure(event, error);
    }
}
예제 #6
0
파일: threadsay.c 프로젝트: wadee/go_proj
void buf_write_callback(struct bufferevent *incoming,
                        void *arg)
{	
    conn *c;
    c = (conn*) arg;
    assert(c != NULL);
    int fd;
    fd = (int)bufferevent_getfd(incoming);
    if (fd != c->sfd){
		perror("fd != sfd");
		conn_close(c);
		return;
	}
	drive_machine(c, incoming);
	return;
}
예제 #7
0
void QueryListener::onEvent(bufferevent *bufEvent, short events, void *arg) {

    QueryListener *_this = static_cast<QueryListener *>(arg);
    evutil_socket_t fd = bufferevent_getfd(bufEvent);

    // If socket is closed - delete it from the collection
    if (events & BEV_EVENT_EOF) {
        LogD(TAG, "event: BEV_EVENT_EOF fd=" + std::to_string(fd));
        _this->connections.erase(bufEvent);
    }

    if (events & BEV_EVENT_ERROR) {
        LogD(TAG, "event: BEV_EVENT_ERROR fd=" + std::to_string(fd));
    }

}
예제 #8
0
const string TcpTransport::getPeerAddrAndPort() {
  struct sockaddr_in broker;
  socklen_t cLen = sizeof(broker);

  // getsockname(m_socket->getRawSocketHandle(), (struct sockaddr*) &s, &sLen);
  // // ! use connectSock here.
  getpeername(bufferevent_getfd(m_bufferEvent), (struct sockaddr *)&broker,
              &cLen);  // ! use connectSock here.
  LOG_DEBUG("broker addr: %s, broker port: %d", inet_ntoa(broker.sin_addr),
            ntohs(broker.sin_port));
  string brokerAddr(inet_ntoa(broker.sin_addr));
  brokerAddr.append(":");
  string brokerPort(UtilAll::to_string(ntohs(broker.sin_port)));
  brokerAddr.append(brokerPort);
  LOG_DEBUG("brokerAddr:%s", brokerAddr.c_str());
  return brokerAddr;
}
예제 #9
0
/* eventcb for bufferevent. For the purpose of simplicity and
   readability of the example program, we omitted the certificate and
   peer verification. After SSL/TLS handshake is over, initialize
   nghttp2 library session, and send client connection header. Then
   send HTTP request. */
static void eventcb(struct bufferevent *bev, short events, void *ptr) {
  http2_session_data *session_data = (http2_session_data *)ptr;
  if (events & BEV_EVENT_CONNECTED) {
    int fd = bufferevent_getfd(bev);
    int val = 1;
    const unsigned char *alpn = NULL;
    unsigned int alpnlen = 0;
    SSL *ssl;

    fprintf(stderr, "Connected\n");

    ssl = bufferevent_openssl_get_ssl(session_data->bev);

#ifndef OPENSSL_NO_NEXTPROTONEG
    SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
    if (alpn == NULL) {
      SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
    }
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */

    if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
      fprintf(stderr, "h2 is not negotiated\n");
      delete_http2_session_data(session_data);
      return;
    }

    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
    initialize_nghttp2_session(session_data);
    send_client_connection_header(session_data);
    submit_request(session_data);
    if (session_send(session_data) != 0) {
      delete_http2_session_data(session_data);
    }
    return;
  }
  if (events & BEV_EVENT_EOF) {
    warnx("Disconnected from the remote host");
  } else if (events & BEV_EVENT_ERROR) {
    warnx("Network error");
  } else if (events & BEV_EVENT_TIMEOUT) {
    warnx("Timeout");
  }
  delete_http2_session_data(session_data);
}
예제 #10
0
파일: socket.c 프로젝트: Apploud/rum
void cache_init_packet_from_server() {
	socklen_t len;
	struct bufferevent *bev;
	struct bev_arg *bev_arg;

	struct destination *destination=first_destination;
	struct sockaddr *s;

	bev = bufferevent_socket_new(event_base, -1, BEV_OPT_CLOSE_ON_FREE);

	bev_arg=malloc(sizeof (struct bev_arg));

	bev_arg->type=BEV_CACHE;
	bev_arg->bev=bev;
	bev_arg->remote=NULL;

	/* set callback functions and argument */
	bufferevent_setcb(bev, cache_mysql_init_packet_read_callback, NULL, cache_mysql_init_packet_event_callback, (void *)bev_arg);

	/* read buffer 64kb */
	bufferevent_setwatermark(bev, EV_READ, 0, INPUT_BUFFER_LIMIT);

	if (destination->s[0] == SOCKET_TCP) {
		s = (struct sockaddr *) &destination->sin;
		len = destination->addrlen;
	} else {
		s = (struct sockaddr *) &destination->sun;
		len = destination->addrlen;
	}

	/* event_callback() will be called after nonblock connect() return 
	 */
	if (bufferevent_socket_connect(bev, s, len)==-1) {
		bufferevent_free(bev);
		free(bev_arg);
	}

	struct linger l;

	l.l_onoff=1;
	l.l_linger=0;

	setsockopt(bufferevent_getfd(bev), SOL_SOCKET, SO_LINGER, (void *) &l, sizeof (l));

	bufferevent_enable(bev, EV_READ);
}
예제 #11
0
파일: server.cpp 프로젝트: amumu/gaston_c
void read_cb(struct bufferevent *bev, void *arg) {
#define MAX_LINE    2560
    char line[MAX_LINE + 1];
    char output[1000];
    int n;
    evutil_socket_t fd = bufferevent_getfd(bev);

    while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) {
        line[n] = '\0';
        printf("fd=%u, read line: %s\n", fd, line);
        worker((int) fd, line, output);
        printf("out line: %s,len=%d\n", output,strlen(output));

        bufferevent_write(bev, output, strlen(output));
    }
    //close(fd);
}
예제 #12
0
파일: threadsay.c 프로젝트: wadee/go_proj
// 改成用bufferevent之后,接受的参数得改。。。
void event_handler(struct bufferevent *incoming, void *arg) {
    conn *c;
    c = (conn *)arg;

    assert(c != NULL);
    // c->which = which;
    int fd;
    fd = (int)bufferevent_getfd(incoming);

    if (fd != c->sfd)
    {
        perror("fd != sfd");
        conn_close(c);
        return;
    }
    drive_machine(c, incoming);
    return;

}
예제 #13
0
void MessageManager::ErrorDispatcher(struct bufferevent *bev, short error, void *ctx)
{
	if(error & BEV_EVENT_CONNECTED)
	{
		LOG(DEBUG, "New connection established", "");
		return;
	}

	if(error & (BEV_EVENT_EOF | BEV_EVENT_ERROR))
	{
		//If we're a server...
		if(ctx != NULL)
		{
			bufferevent_free(bev);
			MessageManager::Instance().DeleteEndpoint(bufferevent_getfd(bev));
		}
		return;
	}
}
예제 #14
0
zend_string * ion_stream_get_name_remote(ion_stream * stream) {
    int type   = 0;
    evutil_socket_t socket;
    if(stream->name_remote == NULL) {
        if(!stream->buffer) {
            return NULL;
        }
        socket = bufferevent_getfd(stream->buffer);
        if(socket == -1) {
            return NULL;
        } else {
            type = pion_net_sock_name(socket, PION_NET_NAME_REMOTE, &stream->name_remote);
            if(type == PION_NET_NAME_UNKNOWN || type == FAILURE) {
                return NULL;
            }
        }
    }
    return zend_string_copy(stream->name_remote);
}
예제 #15
0
static void
ssh_handshake_cb(obfsproxyssh_client_session_t *session)
{
	int rval;
	evutil_socket_t fd = bufferevent_getfd(session->ssh_ev);

	rval = libssh2_session_handshake(session->ssh_session, fd);
	if (LIBSSH2_ERROR_EAGAIN == rval)
		return;
	else if (0 != rval || 0 != ssh_validate_hostkey(session)) {
		libssh2_session_free(session->ssh_session);
		session->ssh_session = NULL;
		session_free(session);
		return;
	}

	session->libssh2_cb = ssh_auth_cb;
	session->libssh2_cb(session);
}
예제 #16
0
void TcpTransport::eventcb(struct bufferevent *bev, short what, void *ctx) {
  evutil_socket_t fd = bufferevent_getfd(bev);
  TcpTransport *tcpTrans = (TcpTransport *)ctx;
  LOG_INFO("eventcb: received event:%x on fd:%d", what, fd);
  if (what & BEV_EVENT_CONNECTED) {
    int val = 1;
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
    LOG_INFO("eventcb:connect to fd:%d successfully", fd);
    tcpTrans->setTcpConnectEvent(e_connectSuccess);
  } else if (what & (BEV_EVENT_ERROR | BEV_EVENT_EOF | BEV_EVENT_READING |
                     BEV_EVENT_WRITING)) {
    LOG_INFO("eventcb:rcv error event cb:%x on fd:%d", what, fd);
    tcpTrans->setTcpConnectEvent(e_connectFail);
    bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
    // bufferevent_disable(bev, EV_READ|EV_WRITE);
    // bufferevent_free(bev);
  } else {
    LOG_ERROR("eventcb: received error event:%d on fd:%d", what, fd);
  }
}
예제 #17
0
static void connecting_event_cb(struct bufferevent *bev, short what, void *arg)
{
	CONNECTOR *cr = (CONNECTOR *)arg;

	if (!(what & BEV_EVENT_CONNECTED))
	{
		PUTS("connecting failed!, %d", time(NULL) );
		if (0 == cr->keep_connect)
		{
			CONNECTOR_CALLBACK *cb = cr->cb;
			if ( cb->onConnect)
				(*(cb->onConnect))(cr, 0);
		}
		else
		{
			//delay_connecting(c);
			reconnect(cr, 5);
		}
	}
	else
	{

		CONNECTOR_CALLBACK *cb = cr->cb;
		int fd = bufferevent_getfd(bev);
		struct linger l;

		PUTS("connect %s success!%d", cr->addrtext, time(NULL));
		cr->state = STATE_CONNECTED;

		if (cb->onConnect)
			(*(cb->onConnect))(cr, 1);

		/* prevent CLOSE_WAIT */
		l.l_onoff = 1;
		l.l_linger = 0;
		setsockopt(fd, SOL_SOCKET, SO_LINGER, (const char *)&l, sizeof(l));
		bufferevent_setcb(bev, read_client_cb, conn_write_cb, conn_event_cb2, cr);
		bufferevent_enable(bev, EV_READ);

	}
}
예제 #18
0
void read_cb(struct bufferevent *bev, void *arg)
{
#define MAX_LINE    256
    char line[MAX_LINE+1];
    int n;
    evutil_socket_t fd = bufferevent_getfd(bev);
    net_para_t net;

    while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) {
        line[n] = '\0';
        printf("fd=%u, read line: %s\n", fd, line);

        net.net = bev;
        net.print = net_print;
        parse_and_exec_cmd(line, ifs_cmd_list, &net);

        line[0] = '>';
        line[1] = 0;
        bufferevent_write(bev, line, 2);
    }
}
예제 #19
0
//解析从Server发出的数据
bool TcpClient::DealWithData(struct bufferevent *bev, const char*pData, int nLen)
{
    evutil_socket_t fd = bufferevent_getfd(bev);
    struct sockaddr_in sin;
    int nsocketLen = sizeof(SOCKADDR);
    char cIPParse[16];
    ushort port;
    if (getpeername(fd, (struct sockaddr*)&sin, &nsocketLen) == 0)
    {
        inet_ntop(AF_INET, (void *)&sin.sin_addr, cIPParse, 16);
        port = ntohs(sin.sin_port);
    }

    m_pPacket->AppendRecvData(nLen, (byte*)pData);
    SolarPacket* pPacketData = m_pPacket->PullRecvPacket();
    if (pPacketData != NULL)
    {
        switch (pPacketData->byteCmd)
        {
        case 0x10:
            break;
        case 0x11:
            break;
        case 0x12:
            break;
        case 0x13:
            break;
        case 0x14:
            break;
        case 0x15:
            break;
        }

        SolarTcpIpPacket::DestroySolarPacket(pPacketData);
    }
    return false;
}
예제 #20
0
파일: utils.c 프로젝트: rampageX/redsocks
struct bufferevent* red_connect_relay(const char *ifname,
                                    struct sockaddr_in *addr,
                                    bufferevent_data_cb readcb,
                                    bufferevent_data_cb writecb,
                                    bufferevent_event_cb errorcb,
                                    void *cbarg,
                                    const struct timeval *timeout_write)
{
    struct bufferevent *retval = NULL;
    int relay_fd = -1;
    int error;

    retval = red_prepare_relay(ifname, readcb, writecb, errorcb, cbarg);
    if (retval) {
        relay_fd = bufferevent_getfd(retval);
        if (timeout_write)
            bufferevent_set_timeouts(retval, NULL, timeout_write);

        //  error = bufferevent_socket_connect(retval, (struct sockaddr*)addr, sizeof(*addr));
        //  if (error) {
        error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr));
        if (error && errno != EINPROGRESS) {
            log_errno(LOG_NOTICE, "connect");
            goto fail;
        }
    }
    return retval;

fail:
    if (retval) {
        bufferevent_disable(retval, EV_READ|EV_WRITE);
        bufferevent_free(retval);
    }
    if (relay_fd != -1)
        redsocks_close(relay_fd);
    return NULL;
}
예제 #21
0
// error event socket ( all client socket)
// connecting socket (client side client)
static void sock_buffer_error_event(bufferevent *bev, short what, void *arg)
{
    coro_sock *sock = (coro_sock *)arg;
    coro_event ev;
    ev.sock = bufferevent_getfd(bev);
    ev.sock = sock->sock;
    if ( what & BEV_EVENT_ERROR ) {
        SET_ERROR(sock->status);
        ev.event = SOCK_ERROR_NOTIFY;
    }
    else if ( what & BEV_EVENT_EOF ) {
        ev.event = SOCK_EOF_NOTIFY;
        SET_EOF(sock->status);
        if ( evbuffer_get_length(bufferevent_get_input(sock->bev)) ) {
            SET_READ(sock->status);
            // printf("set read: %d\n", ev.sock);
        }
    }
    else {
        ; // pass
    }
    sock->ctx->curev.push(ev);
    coro_yield_uthread(__g_coroutine_ctx->io, 0);
}
예제 #22
0
int
bufferevent_socket_connect(struct bufferevent *bev,
    struct sockaddr *sa, int socklen)
{
	struct bufferevent_private *bufev_p =
	    EVUTIL_UPCAST(bev, struct bufferevent_private, bev);

	evutil_socket_t fd;
	int r = 0;
	int result=-1;
	int ownfd = 0;

	bufferevent_incref_and_lock_(bev);

	if (!bufev_p)
		goto done;

	fd = bufferevent_getfd(bev);
	if (fd < 0) {
		if (!sa)
			goto done;
		fd = evutil_socket_(sa->sa_family,
		    SOCK_STREAM|EVUTIL_SOCK_NONBLOCK, 0);
		if (fd < 0)
			goto done;
		ownfd = 1;
	}
	if (sa) {
#ifdef _WIN32
		if (bufferevent_async_can_connect_(bev)) {
			bufferevent_setfd(bev, fd);
			r = bufferevent_async_connect_(bev, fd, sa, socklen);
			if (r < 0)
				goto freesock;
			bufev_p->connecting = 1;
			result = 0;
			goto done;
		} else
#endif
		r = evutil_socket_connect_(&fd, sa, socklen);
		if (r < 0)
			goto freesock;
	}
#ifdef _WIN32
	/* ConnectEx() isn't always around, even when IOCP is enabled.
	 * Here, we borrow the socket object's write handler to fall back
	 * on a non-blocking connect() when ConnectEx() is unavailable. */
	if (BEV_IS_ASYNC(bev)) {
		event_assign(&bev->ev_write, bev->ev_base, fd,
		    EV_WRITE|EV_PERSIST, bufferevent_writecb, bev);
	}
#endif
	bufferevent_setfd(bev, fd);
	if (r == 0) {
		if (! be_socket_enable(bev, EV_WRITE)) {
			bufev_p->connecting = 1;
			result = 0;
			goto done;
		}
	} else if (r == 1) {
		/* The connect succeeded already. How very BSD of it. */
		result = 0;
		bufev_p->connecting = 1;
		event_active(&bev->ev_write, EV_WRITE, 1);
	} else {
		/* The connect failed already.  How very BSD of it. */
		bufev_p->connection_refused = 1;
		bufev_p->connecting = 1;
		result = 0;
		event_active(&bev->ev_write, EV_WRITE, 1);
	}

	goto done;

freesock:
	bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR);
	if (ownfd)
		evutil_closesocket(fd);
	/* do something about the error? */
done:
	bufferevent_decref_and_unlock_(bev);
	return result;
}
예제 #23
0
파일: socket.c 프로젝트: Apploud/rum
/*
 * accept socket, then create buffer events for self and remote
 */
void accept_connect(int sock, short event, void *arg) {
	struct listener *listener=(struct listener *)arg;
	socklen_t len;
	struct sockaddr_in sin;
	struct sockaddr_un sun;
	int csock=0;
	struct bufferevent *bev_client, *bev_target;
	struct bev_arg *bev_arg_client, *bev_arg_target;

	struct destination *destination=first_destination;
	struct sockaddr *s=NULL;

	if (listener->s[0]==SOCKET_TCP) {
		len = sizeof(struct sockaddr_in);
		s = (struct sockaddr *) &sin;
	} else if (listener->s[0]==SOCKET_UNIX) {
		len = sizeof(struct sockaddr_un);
		s = (struct sockaddr *) &sun;
	}

	csock=accept(sock, s, &len);

	if (csock==-1) {
		return;
	}

	fcntl(csock, F_SETFL, O_RDWR|O_NONBLOCK);

	listener->nr_allconn++;

	/* the first turn the switch on */
	/* the last turn the switch off*/
	listener->nr_conn++;

	bev_client = bufferevent_socket_new(event_base, csock, BEV_OPT_CLOSE_ON_FREE);
	bev_target = bufferevent_socket_new(event_base, -1, BEV_OPT_CLOSE_ON_FREE);

	/* CLIENT bev_arg*/
	/* parameter for callback functions */
	bev_arg_client=malloc(sizeof (struct bev_arg));
	bev_arg_client->type=BEV_CLIENT;
	bev_arg_client->listener=listener;
	bev_arg_client->bev=bev_client;
	bev_arg_client->connecting=0;

	/* set callback functions and argument */
	if (listener->type==LISTENER_DEFAULT) {
		if (!mysql_cdb_file) {
			bufferevent_setcb(bev_client, read_callback, NULL, event_callback, (void *)bev_arg_client);
		} else {
			/* if mysql_cdb is enabled, use different callback functions */
			bev_arg_client->ms=init_ms();
			bufferevent_setcb(bev_client, mysql_read_callback, NULL, mysql_event_callback, (void *)bev_arg_client);
		}
	} else if (listener->type==LISTENER_STATS) {
		bufferevent_setcb(bev_client, NULL, stats_write_callback, stats_event_callback, (void *)bev_arg_client);
		send_stats_to_client(bev_client);

		return;
	}
	/* read buffer 64kb */
	bufferevent_setwatermark(bev_client, EV_READ, 0, INPUT_BUFFER_LIMIT);

	/* TARGET bev_arg*/
	/* parameter for callback functions */
	bev_arg_target=malloc(sizeof (struct bev_arg));
	bev_arg_target->type=BEV_TARGET;
	bev_arg_target->connecting=0;

	bev_arg_client->remote=bev_arg_target;

	/* set callback functions and argument */
	bev_arg_target->listener=listener;
	bev_arg_target->bev=bev_target;
	bev_arg_target->remote=bev_arg_client;

	if (!mysql_cdb_file) {
		bufferevent_setcb(bev_target, read_callback, NULL, event_callback, (void *)bev_arg_target);
	} else {
		/* mysql_stuff structure is same for client and target bufferevent */
		bev_arg_target->ms=bev_arg_client->ms;

		bufferevent_setcb(bev_target, mysql_read_callback, NULL, mysql_event_callback, (void *)bev_arg_target);
	}
	/* read buffer 64kb */
	bufferevent_setwatermark(bev_target, EV_READ, 0, INPUT_BUFFER_LIMIT);

	if (destination->s[0] == SOCKET_TCP) {
		s = (struct sockaddr *) &destination->sin;
		len = destination->addrlen;
	} else {
		s = (struct sockaddr *) &destination->sun;
		len = destination->addrlen;
	}

	/* we can use cached init packet only if we can use MITM attack,
	 * we can use MITM attack only if we use mysql_cdb_file where are hashed user passwords
	 */
	if (!mysql_cdb_file || (mysql_cdb_file && !cache_mysql_init_packet)) {
		bev_arg_target->connecting=1;
		if (bufferevent_socket_connect(bev_target, s, len)==-1) {
			listener->nr_conn--;
			bufferevent_free(bev_client);
			bufferevent_free(bev_target);
			free(bev_arg_client);
			free(bev_arg_target);
		}
		bev_arg_target->connecting=0;
		struct linger l;

		l.l_onoff=1;
		l.l_linger=0;

		setsockopt(bufferevent_getfd(bev_target), SOL_SOCKET, SO_LINGER, (void *) &l, sizeof (l));
	} else {
		/* use cached init packet */
		bev_arg_client->remote=NULL;
		bev_arg_client->ms->not_need_remote=1;
		bev_arg_client->ms->handshake=1;
		/* we use bev_arg_client and ms pointers as random data for generating random string filled in init packet send to client */
		/* TODO: use better random input */
		bev_arg_client->ms->scramble1=set_random_scramble_on_init_packet(cache_mysql_init_packet, bev_arg_target, bev_arg_client->ms);

		bufferevent_free(bev_target);
		free(bev_arg_target);

		if (bufferevent_write(bev_client, cache_mysql_init_packet, cache_mysql_init_packet_len)==-1) {
			listener->nr_conn--;
			bufferevent_free(bev_client);
			bufferevent_free(bev_target);
			free(bev_arg_client);
			free(bev_arg_target);
		}

		bufferevent_enable(bev_client, EV_READ);
	}
}
예제 #24
0
static void on_read(struct bufferevent *bev, void *ctx) {
    struct evbuffer *input;
    int fd;
    size_t len;

    char *line;
    char *emsg;

    char **argv = malloc(sizeof(char *));
    int argc = 0;
    char *arg_ptr, *save_ptr;

    /*
     * 1: Unknown command
     * 2: Too few arguments
     * 3: Internal error
     * 4: Missing command
     */
    int status;
    int i;

    input = bufferevent_get_input(bev);
    fd = bufferevent_getfd(bev);

    len = evbuffer_get_length(input);
    line = malloc(len + 1);
    evbuffer_copyout(input, line, len);

    if (len == 0) {
        status = 4;
        goto END;
    }

    if (line[len - 1] == '\n') {
        line[len - 1] = 0;
    } else {
        line[len] = 0;
    }

    arg_ptr = strtok_r(line, " ", &save_ptr);
    while (arg_ptr != NULL) {
        len = strlen(arg_ptr) + 1;

        argv[argc] = malloc(len);
        strncpy(argv[argc], arg_ptr, len);
        argv = realloc(argv, argc + 1);

        arg_ptr = strtok_r(NULL, " ", &save_ptr);

        argc++;
    }

    printf("%s LookingGlass: Received command \"%s\" with %d arguments", date(), argv[0], argc - 1);
    for (i = 1; i < argc; i++) {
        printf(" %d:\"%s\"", i, argv[i]);
    }
    printf(".\n");

    status = call_function(argv[0], fd, argc, argv);

END:
    switch (status) {
    case 1:
        emsg = "Unknown command";
        write(fd, emsg, strlen(emsg));
        fprintf(stdout, "%s LookingGlass: Error: Disconnecting client. Reason: %s: %s.\n", date(), emsg, argv[0]);
        break;
    case 2:
        emsg = "Too few arguments";
        write(fd, emsg, strlen(emsg));
        fprintf(stdout, "%s LookingGlass: Disconnecting client. Error: %s.\n", date(), emsg);
        break;
    case 3:
        emsg = "Internal error";
        write(fd, emsg, strlen(emsg));
        fprintf(stdout, "%s LookingGlass: Disconnecting client. Error: %s.\n", date(), emsg);
        break;
    case 4:
        emsg = "Missing command";
        write(fd, emsg, strlen(emsg));
        fprintf(stdout, "%s LookingGlass: Disconnecting client. Error: %s.\n", date(), emsg);
        break;
    default:
        printf("%s LookingGlass: Disconnecting client.\n", date());
        break;
    }

    bufferevent_free(bev);

    for (i = 0; i < argc; i++) {
        free(argv[i]);
    }
    free(argv);
    free(line);
}
예제 #25
0
파일: utils.c 프로젝트: rampageX/redsocks
struct bufferevent* red_connect_relay_tfo(const char *ifname,
                                    struct sockaddr_in *addr,
                                    bufferevent_data_cb readcb,
                                    bufferevent_data_cb writecb,
                                    bufferevent_event_cb errorcb,
                                    void *cbarg,
                                    const struct timeval *timeout_write,
                                    void *data,
                                    size_t *len)
{
    struct bufferevent *retval = NULL;
    int relay_fd = -1;
    int error;

    retval = red_prepare_relay(ifname, readcb, writecb, errorcb, cbarg);
    if (retval) {
        relay_fd = bufferevent_getfd(retval);
        if (timeout_write)
            bufferevent_set_timeouts(retval, NULL, timeout_write);

#ifdef MSG_FASTOPEN
        size_t s = sendto(relay_fd, data, * len, MSG_FASTOPEN,
                (struct sockaddr *)addr, sizeof(*addr)
                );
        *len = 0; // Assume nothing sent, caller needs to write data again when connection is setup.
        if (s == -1) {
            if (errno == EINPROGRESS || errno == EAGAIN
                    || errno == EWOULDBLOCK) {
                // Remote server doesn't support tfo or it's the first connection to the server.
                // Connection will automatically fall back to conventional TCP.
                log_error(LOG_DEBUG, "TFO: no cookie");
                return retval;
            } else if (errno == EOPNOTSUPP || errno == EPROTONOSUPPORT ||
                    errno == ENOPROTOOPT) {
                // Disable fast open as it's not supported
                log_error(LOG_DEBUG, "TFO: not support");
                goto fallback;
            } else {
                log_errno(LOG_NOTICE, "sendto");
                goto fail;
            }
        }
        else {
            log_error(LOG_DEBUG, "TFO: cookie found");
            *len = s; // data is put into socket buffer
            return retval;
        }
fallback:
#endif

        error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr));
        if (error && errno != EINPROGRESS) {
            log_errno(LOG_NOTICE, "connect");
            goto fail;
        }
        // write data to evbuffer so that data can be sent when connection is set up
        if (bufferevent_write(retval, data, *len) != 0) {
            log_errno(LOG_NOTICE, "bufferevent_write");
            *len = 0; // Nothing sent, caller needs to write data again when connection is setup.
            goto fail;
        }
    }
    return retval;

fail:
    if (retval) {
        bufferevent_disable(retval, EV_READ|EV_WRITE);
        bufferevent_free(retval);
    }
    if (relay_fd != -1)
        redsocks_close(relay_fd);
    return NULL;
}
예제 #26
0
파일: utils.c 프로젝트: rampageX/redsocks
struct bufferevent* red_connect_relay_ssl(const char *ifname,
                                    struct sockaddr_in *addr,
                                    SSL * ssl,
                                    bufferevent_data_cb readcb,
                                    bufferevent_data_cb writecb,
                                    bufferevent_event_cb errorcb,
                                    void *cbarg,
                                    const struct timeval *timeout_write)
{
    struct bufferevent *retval = NULL;
    struct bufferevent *underlying = NULL;
    int relay_fd = -1;
    int error;

    underlying = red_prepare_relay(ifname, NULL, NULL, NULL, NULL);
    if (!underlying)
        goto fail;
    relay_fd = bufferevent_getfd(underlying);
    if (timeout_write)
        bufferevent_set_timeouts(underlying, NULL, timeout_write);

    error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr));
    if (error && errno != EINPROGRESS) {
        log_errno(LOG_NOTICE, "connect");
        goto fail;
    }
    retval = bufferevent_openssl_filter_new(bufferevent_get_base(underlying),
                                            underlying,
                                            ssl,
                                            BUFFEREVENT_SSL_CONNECTING,
                                            BEV_OPT_DEFER_CALLBACKS);
    if (!retval) {
        log_errno(LOG_NOTICE, "bufferevent_openssl_filter_new");
        goto fail;
    }
    if (timeout_write)
        bufferevent_set_timeouts(retval, NULL, timeout_write);

    bufferevent_setcb(retval, readcb, writecb, errorcb, cbarg);
    if (writecb) {
        error = bufferevent_enable(retval, EV_WRITE); // we wait for connection...
        if (error) {
            log_errno(LOG_ERR, "bufferevent_enable");
            goto fail;
        }
    }
    return retval;

fail:
    if (retval) {
        bufferevent_disable(retval, EV_READ|EV_WRITE);
        bufferevent_free(retval);
    }
    if (underlying) {
        bufferevent_disable(underlying, EV_READ|EV_WRITE);
        bufferevent_free(underlying);
    }
    if (relay_fd != -1)
        redsocks_close(relay_fd);
    return NULL;
}
예제 #27
0
void ConnectionWrapper::init(bufferevent *bufEvent) {
    assert(bufEvent != nullptr);
    this->bufEvent = bufEvent;
    this->fd = bufferevent_getfd(bufEvent);
    LogD(TAG, "Connection established fd=" + std::to_string(fd));
}
예제 #28
0
bool ConnectToNovad()
{
	if(IsNovadUp(false))
	{
		return true;
	}

	DisconnectFromNovad();

	//Create new base
	if(libeventBase == NULL)
	{
		evthread_use_pthreads();
		libeventBase = event_base_new();
		pthread_mutex_init(&bufferevent_mutex, NULL);
	}

	//Builds the key path
	string key = Config::Inst()->GetPathHome();
	key += "/config/keys";
	key += NOVAD_LISTEN_FILENAME;

	//Builds the address
	struct sockaddr_un novadAddress;
	novadAddress.sun_family = AF_UNIX;
	memset(novadAddress.sun_path, '\0', sizeof(novadAddress.sun_path));
	strncpy(novadAddress.sun_path, key.c_str(), sizeof(novadAddress.sun_path));

	{
		Lock buffereventLock(&bufferevent_mutex);
		bufferevent = bufferevent_socket_new(libeventBase, -1,
				BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE |  BEV_OPT_UNLOCK_CALLBACKS | BEV_OPT_DEFER_CALLBACKS );
		if(bufferevent == NULL)
		{
			LOG(ERROR, "Unable to create a socket to Nova", "");
			DisconnectFromNovad();
			return false;
		}

		bufferevent_setcb(bufferevent, MessageManager::MessageDispatcher, NULL, MessageManager::ErrorDispatcher, NULL);

		if(bufferevent_enable(bufferevent, EV_READ) == -1)
		{
			LOG(ERROR, "Unable to enable socket events", "");
			return false;
		}

		if(bufferevent_socket_connect(bufferevent, (struct sockaddr *)&novadAddress, sizeof(novadAddress)) == -1)
		{
			bufferevent = NULL;
			LOG(DEBUG, "Unable to connect to NOVAD: "+string(strerror(errno))+".", "");
			return false;
		}

		IPCSocketFD = bufferevent_getfd(bufferevent);
		if(IPCSocketFD == -1)
		{
			LOG(DEBUG, "Unable to connect to Novad: "+string(strerror(errno))+".", "");
			bufferevent_free(bufferevent);
			bufferevent = NULL;
			return false;
		}

		if(evutil_make_socket_nonblocking(IPCSocketFD) == -1)
		{
			LOG(DEBUG, "Unable to connect to Novad", "Could not set socket to non-blocking mode");
			bufferevent_free(bufferevent);
			bufferevent = NULL;
			return false;
		}

		MessageManager::Instance().DeleteEndpoint(IPCSocketFD);
		MessageManager::Instance().StartSocket(IPCSocketFD, bufferevent);
	}
	pthread_create(&eventDispatchThread, NULL, EventDispatcherThread, NULL);

	//Test if the connection is up
	Ticket ticket = MessageManager::Instance().StartConversation(IPCSocketFD);

	RequestMessage connectRequest(REQUEST_PING);
	if(!MessageManager::Instance().WriteMessage(ticket, &connectRequest))
	{
		return false;
	}

	Message *reply = MessageManager::Instance().ReadMessage(ticket);
	if(reply->m_messageType == ERROR_MESSAGE && ((ErrorMessage*)reply)->m_errorType == ERROR_TIMEOUT)
	{
		LOG(DEBUG, "Timeout error when waiting for message reply", "");
		delete reply;
		return false;
	}

	if(reply->m_messageType != REQUEST_MESSAGE)
	{
		stringstream s;
		s << "Expected message type of REQUEST_MESSAGE but got " << reply->m_messageType;
		LOG(DEBUG, s.str(), "");

		reply->DeleteContents();
		delete reply;
		return false;
	}
	RequestMessage *connectionReply = (RequestMessage*)reply;
	if(connectionReply->m_contents.m_requesttype() != REQUEST_PONG)
	{
		stringstream s;
		s << "Expected control type of CONTROL_CONNECT_REPLY but got " <<connectionReply->m_contents.m_requesttype();
		LOG(DEBUG, s.str(), "");

		reply->DeleteContents();
		delete reply;
		return false;
	}
	delete connectionReply;

	return true;
}
예제 #29
0
static void
echo_read_cb(struct bufferevent *bev, void *ctx)
{
    printf("echo_read_cb ctx:%p\n", ctx);
    /* This callback is invoked when there is data to read on bev. */
    struct evbuffer *input = bufferevent_get_input(bev);

    /* Copy all the data from the input buffer to the output buffer. */
    // evbuffer_add_buffer(output, input);
    // 能读到数据的时候 去连接其他server 而且是以阻塞的方式

    printf("echo_read_cb1 \n");
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    //servaddr.sin_family = AF_INET;
    ////servaddr.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
    //if (inet_aton("192.168.1.104", &servaddr.sin_addr) == 0)
    //{
    //	perror("inet_aton failure!");
    //	printf("address:%u\n", servaddr.sin_addr.s_addr);
    //	exit(EXIT_FAILURE);
    //}

    //servaddr.sin_port = htons(5188); /* Port 9876*/

    // TODO 错误判断
    char buff[64];
    evutil_snprintf(buff, sizeof(buff), "%s:%d", "192.168.1.104", 5188);
    int servadd_len = sizeof(servaddr);
    //int retx = evutil_parse_sockaddr_port("192.168.1.104:5188", (struct sockaddr*)&servaddr, &servadd_len);
    int retx = evutil_parse_sockaddr_port(buff, (struct sockaddr*)&servaddr, &servadd_len);

    printf("address:%s\n", buff);
    if (retx < 0)
    {
        printf("address:error\n");
    }
    else
    {
        printf("address:%u\n", servaddr.sin_addr.s_addr);
    }
    int sockconn;
    errno = 0;
    if ((sockconn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        perror("socket failure");
        exit(EXIT_FAILURE);
    }
    //evutil_make_socket_nonblocking(sockconn);

    struct timeval	tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    setsockopt(sockconn, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    setsockopt(sockconn, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
    // bufferevent_socket_new 只是分配内存 没有系统调用
    struct bufferevent *bev1 = bufferevent_socket_new(ctx, sockconn, BEV_OPT_CLOSE_ON_FREE);
    //bufferevent_settimeout(bev1, 10, 10);
    //bev1 = bufferevent_socket_new(ctx, -1, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_enable(bev1, EV_READ|EV_WRITE);
    bufferevent_setcb(bev1, NULL, NULL, eventcb, "hello");
    //SetSocketBlockingEnabled(sockconn, 1);

    // 这里默认是阻塞的,会一直阻塞 直到连接成功 或超时 // //
    if (bufferevent_socket_connect(bev1,
                                   (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        /* Error starting connection */
        // 连接不能马上建立的时候 应该添加到写事件中
        fprintf(stderr, "Connect failed.\n");
        perror("connect...........");
        //#define	ETIMEDOUT	110	/* Connection timed out */
        // 无条件超时 非自定义超时  走这里//
        //bufferevent_free(bev1);
        // 此时错误码是 BEV_EVENT_ERROR 在那里销毁 BEV_EVENT_ERROR
        //return -1;
        // 110错误码走到这里  11, 115错误码 不会走到这里
    }
    printf("bufferevent_socket_connect return errno:%d \n", errno);
    ////#define	EAGAIN		11	/* Try again */
    ////#define	ECONNREFUSED	111	/* Connection refused */
    ////#define	EINPROGRESS	115	/* Operation now in progress */ // connect 被超时打断11,


    //
    //if (errno != EAGAIN )
    if (errno == EINPROGRESS) // 自定义 超时中断
    {
        perror("self timeout.............");
        bufferevent_free(bev1);
        return;
    }
    else if (errno != 0)
    {
        perror("00buffevent_connect");
        printf("bufferevent_socket_connect error\n");
        //如果 在过程中 超时会被 打断	EINPROGRESS	115	/* Operation now in progress */

        // 除了自定义超时timeout不宜在这里销毁 在 回调函数中销毁 不然调用不到回调函数//

        //bufferevent_free(bev1);
        return ;
    }
    else
    {
        // 连接成功
        perror("11buffevent_connect");
        printf("bufferevent_socket_connect success\n");
    }


    //if (connect(sockconn, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    //{
    //	perror("connnect error");
    //	exit(EXIT_FAILURE);
    //}
    //else
    //{
    //	printf("connect success\n");
    //}

    //char recvbuf[1024] = {0};
    //memset(recvbuf, 0, sizeof(recvbuf));
    //sleep(5);
    //read(sockconn, recvbuf, sizeof(recvbuf));
    //printf("----%s-----\n", recvbuf);

//	struct evbuffer *input1 = bufferevent_get_input(bev1);
//	printf("before read ---------\n");
//	bufferevent_read_buffer(bev1, input1);
//	size_t len =  evbuffer_get_length(input1);
//	unsigned char * recvbuf = evbuffer_pullup(input1, len);
//	printf("end read len:%ld---------\n", len);
//	printf("----%s-----\n", recvbuf);


    //struct evbuffer * buffer =  evbuffer_new();
    struct evbuffer *buffer = bufferevent_get_input(bev1);
    struct evbuffer *buffero = bufferevent_get_output(bev1);
    evutil_socket_t fd =  bufferevent_getfd(bev1);

    time_t rawtime;
    time ( &rawtime );
    printf("before read ---------%ld\n", rawtime);
    int  ret = evbuffer_read(buffer, fd, 1024);
    // not work
    // bufferevent_read_buffer(bev1, buffer);
    size_t len =  evbuffer_get_length(buffer);
    time ( &rawtime );
    printf("end readlen  ---------%ld\n", len);
    unsigned char * recvbuf = evbuffer_pullup(buffer, len);
    printf("end read    ---------%ld\n", rawtime);
    printf("----%s-----\n", recvbuf);
    evbuffer_drain(buffer, len);
    // int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd);
    time ( &rawtime );
    printf("before write---------%ld\n", rawtime);
    sleep(10);
    time ( &rawtime );
    printf("before write1---------%ld\n", rawtime);
    evbuffer_add(buffero, "hello,china", 12);
    ret = evbuffer_write(buffero, fd);
    // ret =write(fd, "hello,china", 12);
    if (ret < 0)
    {
        if (errno != 0)
        {
            perror("write ");
        }
    }

    time ( &rawtime );
    printf("end write1   ---------%ld\n", rawtime);

    // 出现read 在connect 之前//
    //root@debian:~/programming/libevent/libevent2/libevent/sample/study-buffevent_block# ./echoserver_block
    //	create listener success, base:0xfdbc40
    //	echo_read_cb ctx:0xfdbc40
    //	echo_read_cb1
    //	bufferevent_socket_connect return errno:11
    //	11buffevent_connect: Resource temporarily unavailable
    //	bufferevent_socket_connect success
    //	----hello,world-----
    //	Connect okay,-------------------------- hello.
    //	disConnect --------------------------.

}
예제 #30
0
void TcpTransport::readNextMessageIntCallback(struct bufferevent *bev,
                                              void *ctx) {
  /* This callback is invoked when there is data to read on bev. */

  // protocol:  <length> <header length> <header data> <body data>
  //                    1                   2                       3 4
  // rocketmq protocol contains 4 parts as following:
  //     1¡¢big endian 4 bytes int, its length is sum of 2,3 and 4
  //     2¡¢big endian 4 bytes int, its length is 3
  //     3¡¢use json to serialization data
  //     4¡¢application could self-defination binary data

  struct evbuffer *input = bufferevent_get_input(bev);
  while (1) {
    struct evbuffer_iovec v[4];
    int n = evbuffer_peek(input, 4, NULL, v, sizeof(v) / sizeof(v[0]));

    int idx = 0;
    char hdr[4];
    char *p = hdr;
    unsigned int needed = 4;

    for (idx = 0; idx < n; idx++) {
      if (needed) {
        unsigned int tmp = needed < v[idx].iov_len ? needed : v[idx].iov_len;
        memcpy(p, v[idx].iov_base, tmp);
        p += tmp;
        needed -= tmp;
      } else {
        break;
      }
    }

    if (needed) {
      LOG_DEBUG(" too little data received with sum = %d ", 4 - needed);
      return;
    }
    uint32 totalLenOfOneMsg =
        *(uint32 *)hdr;  // first 4 bytes, which indicates 1st part of protocol
    uint32 bytesInMessage = ntohl(totalLenOfOneMsg);
    LOG_DEBUG("fd:%d, totalLen:" SIZET_FMT ", bytesInMessage:%d",
              bufferevent_getfd(bev), v[0].iov_len, bytesInMessage);

    uint32 len = evbuffer_get_length(input);
    if (len >= bytesInMessage + 4) {
      LOG_DEBUG("had received all data with len:%d from fd:%d", len,
                bufferevent_getfd(bev));
    } else {
      LOG_DEBUG(
          "didn't received whole bytesInMessage:%d, from fd:%d, totalLen:%d",
          bytesInMessage, bufferevent_getfd(bev), len);
      return;  // consider large data which was not received completely by now
    }

    if (bytesInMessage > 0) {
      MemoryBlock messageData(bytesInMessage, true);
      uint32 bytesRead = 0;
      char *data = messageData.getData() + bytesRead;
      bufferevent_read(bev, data, 4);
      bytesRead = bufferevent_read(bev, data, bytesInMessage);

      TcpTransport *tcpTrans = (TcpTransport *)ctx;
      tcpTrans->messageReceived(messageData);
    }
  }
}