Esempio n. 1
0
static void
listen_cb(struct evconnlistener *listener, evutil_socket_t fd,
    struct sockaddr *sa, int socklen, void *arg)
{
	struct event_base *base = arg;
	struct bufferevent *bev;
	const char s[] = TEST_STR;
	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
	bufferevent_write(bev, s, sizeof(s));
	bufferevent_setcb(bev, NULL, sender_writecb, sender_errorcb, NULL);
	bufferevent_enable(bev, EV_WRITE);
}
Esempio n. 2
0
 void BufferEvent::SetCallBack(BufferEventDataCallBack *readcb, BufferEventDataCallBack *writecb,
                               BufferEventEvCallBack *eventcb) {
     std::cerr << "Callback set" << std::endl;
     this->readcb_ = readcb;
     this->writecb_ = writecb;
     this->eventcb_ = eventcb;
     bufferevent_setcb(bufev_,
                       _bufev_wrap_read_callback,
                       _bufev_wrap_write_callback,
                       _bufev_wrap_event_callback,
                       (void*)this);
 }
Esempio n. 3
0
void on_accept(int fd,short,void* arg){
	struct event_base* base = reinterpret_cast<struct event_base*>(arg);
	struct sockaddr_in peer_addr;
	memset(&peer_addr,0,sizeof(peer_addr));
	socklen_t len=0;
	int clientfd = accept(fd,(struct sockaddr*)&peer_addr,&len);
	evutil_make_socket_nonblocking(clientfd);
	auto bv = bufferevent_socket_new(base,clientfd,BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bv,readcb,writecb,eventcb,base);
	bufferevent_enable(bv,EV_READ );
	
}
Esempio n. 4
0
void BaseServer::listener_callback(struct evconnlistener *listener, int fd, struct sockaddr *sa, int socklen, void *arg)
{
    event_base *base = (event_base*)arg;
    struct bufferevent* bev = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
    assert(bev);
    bufferevent_setwatermark(bev,EV_READ,0,0);
    bufferevent_setwatermark(bev,EV_WRITE,0,0);

    bufferevent_setcb(bev,read_callback,write_callback,NULL,NULL);
    bufferevent_enable(bev,EV_READ);

}
static void accept_conn_callback(
    struct evconnlistener *listener,
    evutil_socket_t fd,
    struct sockaddr *address,
    int socklen,
    void *context)
{
    struct event_base *base = evconnlistener_get_base(listener);    
    struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(bev, echo_read_cb, NULL, echo_event_cb, NULL);
    bufferevent_enable(bev, EV_READ | EV_WRITE);
}
Esempio n. 6
0
static void
drained_writecb(struct bufferevent *bev, void *ctx)
{
	struct bufferevent *partner = ctx;

	/* We were choking the other side until we drained our outbuf a bit.
	 * Now it seems drained. */
	bufferevent_setcb(bev, readcb, NULL, eventcb, partner);
	bufferevent_setwatermark(bev, EV_WRITE, 0, 0);
	if (partner)
		bufferevent_enable(partner, EV_READ);
}
static void accept_conn_cb(struct evconnlistener *listener,
    evutil_socket_t fd, struct sockaddr *address, int socklen,
    void *ctx)
{
        /* We got a new connection! Set up a bufferevent for it. */
        struct event_base *base = evconnlistener_get_base(listener);
        struct bufferevent *bev = bufferevent_socket_new(
                base, fd, BEV_OPT_CLOSE_ON_FREE);
 
        bufferevent_setcb(bev, echo_read_cb, NULL, echo_event_cb, NULL);
        bufferevent_enable(bev, EV_READ|EV_WRITE);
}
Esempio n. 8
0
static void new_connection(state *s) {
    struct bufferevent *bev;
    struct timeval timeout={3, 0}; /* 3 seconds */

    s->mode=0;
    s->ptr=0;
    s->len=sizeof(record);
    bev=bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
    bufferevent_set_timeouts(bev, &timeout, &timeout);
    bufferevent_setcb(bev, read_cb, write_cb, event_cb, s);
    bufferevent_socket_connect(bev, addr, addr_len);
}
Esempio n. 9
0
void
chlderrcb(struct bufferevent *b, short what, void *arg)
{
	int *nprocs =(int *)arg;

	bufferevent_setcb(b, nil, nil, nil, nil);
	bufferevent_disable(b, EV_READ | EV_WRITE);
	bufferevent_free(b);
	
	/*if(--(*nprocs) == 0)
		event_loopbreak();*/
}
Esempio n. 10
0
static void drone_rampup_timer_cb(evutil_socket_t fd, short what, void *arg) {
    struct job *job = arg;
    Drone__JobRequest *request = job->request;
    struct session *session;
    struct bufferevent *bev;
    struct sockaddr_in echo_sin;
    struct timeval timeout;
    u_int64_t sessions;
    u_int64_t i;

    if (job->client == NULL)
        return;

    if ((request->sessions - job->cur_sessions) > request->rampup_sessions)
        sessions = request->rampup_sessions;
    else
        sessions = request->sessions - job->cur_sessions;

    memset(&echo_sin, 0, sizeof(echo_sin));
    echo_sin.sin_family = AF_INET;
    echo_sin.sin_addr.s_addr = htonl(request->ipv4);
    echo_sin.sin_port = htons(request->port);

    for (i = 0; i < sessions; i++) {
        bev = bufferevent_socket_new(job->client->base, -1,
                BEV_OPT_CLOSE_ON_FREE);

        session = malloc(sizeof(struct session));

        bufferevent_setcb(bev, drone_read_cb, NULL, drone_event_cb, session);
        bufferevent_enable(bev, EV_READ | EV_WRITE);

        timeout.tv_sec = request->timeout;
        timeout.tv_usec = 0;
        bufferevent_set_timeouts(bev, NULL, &timeout);

        if (bufferevent_socket_connect(bev, (struct sockaddr *) &echo_sin,
                sizeof(echo_sin)) < 0) {
            bufferevent_free(bev);
            free(session);
            perror("Error during connection");
            return;
        }

        session->job = job;
        session->bev = bev;
        session->remaining_data = 0;

        job->sessions[job->cur_sessions] = session;
        job->cur_sessions++;
    }
}
Esempio n. 11
0
static void
peers_connect(struct peers* p, int id, struct sockaddr_in* addr)
{
	p->peers = realloc(p->peers, sizeof(struct peer*) * (p->peers_count+1));
	p->peers[p->peers_count] = make_peer(p, id, addr);
	
	struct peer* peer = p->peers[p->peers_count];
	bufferevent_setcb(peer->bev, on_read, NULL, on_peer_event, peer);
	peer->reconnect_ev = evtimer_new(p->base, on_connection_timeout, peer);
	connect_peer(peer);

	p->peers_count++;
}
Esempio n. 12
0
File: conn.c Progetto: 0xffea/shim
static void
finish_connection(struct conninfo *info, int ok, const char *reason)
{
	mem_free(conn_error_string);
	conn_error_string = NULL;
	if (!ok)
		conn_error_string = mem_strdup(reason);
	bufferevent_disable(info->bev, EV_READ);
	bufferevent_setcb(info->bev, NULL, NULL, NULL, NULL);
	info->on_connect(info->bev, ok, info->cbarg);
	mem_free(info->host);
	mem_free(info);
}
Esempio n. 13
0
void
socks_flush(struct socks_data *data)
{
	struct evbuffer *buf;
	buf = bufferevent_get_output(data->bev);
	if (evbuffer_get_length(buf)) {
		bufferevent_disable(data->bev, EV_READ);
		bufferevent_setwatermark(data->bev, EV_WRITE, 0, 16384);
		bufferevent_setcb(data->bev, NULL, socks_flush_fin,
				socks_request_error, data);
	} else
		socks_flush_fin(data->bev, data);
}
Esempio n. 14
0
static void
socks_request_cb(struct bufferevent *bev, void *ctx)
{
	struct socks_data *data = ctx;

	if (evbuffer_get_length(bufferevent_get_input(bev)) < data->req_len) {
		bufferevent_enable(bev, EV_READ);
		bufferevent_setwatermark(bev, EV_READ, data->req_len, 2048);
		bufferevent_setcb(bev, socks_request_cb, NULL,
					socks_request_error, ctx);
	} else
		data->req_cb(ctx);
}
Esempio n. 15
0
	static void
drained_writecbout(struct bufferevent *bev_out, void *ctx_in)
{
	fprintf(stderr, "drained_writecbout adjust the wartermark of <proxy->server>\n");
	struct bufferevent *partner_in = ctx_in;

	/* We were choking the other side until we drained our outbuf a bit.
	 * Now it seems drained. */
	bufferevent_setcb(bev_out, readcbout, NULL, eventcbout, partner_in);
	bufferevent_setwatermark(bev_out, EV_WRITE, 0, 0);
	if (partner_in)
		bufferevent_enable(partner_in, EV_READ);
}
Esempio n. 16
0
static void watcher_new_conn(struct evconnlistener *listener,
			     evutil_socket_t fd, struct sockaddr *address,
			     int socklen, void *vctx)
{
	struct watcher_ctx *ctx = vctx;
	struct bufferevent *bev;

	ctx->refcount++;
	bev = bufferevent_socket_new(ctx->event_base, fd,
				     BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev, NULL, NULL, watcher_conn_closed, vctx);
	bufferevent_enable(bev, EV_READ | EV_WRITE);
}
Esempio n. 17
0
	static void
drained_writecbin(struct bufferevent *bev_in, void *ctx_out)
{
	fprintf(stderr, "drained_writecbin adjust the wartermark of <client-proxy>\n");
	struct bufferevent *partner_out= ctx_out;

	/* We were choking the other side until we drained our outbuf a bit.
	 * Now it seems drained. */
	bufferevent_setcb(bev_in, readcbin, NULL, eventcbin, partner_out);
	bufferevent_setwatermark(bev_in, EV_WRITE, 0, 0);
	if (partner_out)
		bufferevent_enable(partner_out, EV_READ);
}
Esempio n. 18
0
/*
 * if some data are in input buffer, copy it to remote bufferevent output buffer
 */
void read_callback(struct bufferevent *bev, void *ptr)
{
	struct bev_arg *bev_arg=ptr;
	size_t len;

	/* if remote bufferevent exist */
	if (bev_arg->remote) {
		struct bufferevent *bev_remote=bev_arg->remote->bev;

		/* update stats */
		len = evbuffer_get_length(bufferevent_get_input(bev));
		if (len) {
			/* update stats */
			if (bev_arg->type==BEV_CLIENT) {
				bev_arg->listener->input_bytes+=len;
			} else if (bev_arg->type==BEV_TARGET) {
				bev_arg->listener->output_bytes+=len;
			}
		}

		/* write data from our intput buffer to remote output buffer */
		//if (bufferevent_read_buffer(bev, bufferevent_get_output(bev_remote))==-1) {
		if (bufferevent_write_buffer(bev_remote, bufferevent_get_input(bev))==-1) {
			/* if error, close our socket, remote socket and free everything */
			bev_arg->listener->nr_conn--;

			bufferevent_free(bev);
			bufferevent_free(bev_remote);
			free(bev_arg->remote);
			free(bev_arg);

			return;
		}

		/* If remote bufferevent has more data than OUTPUT_BUFFER_LIMIT 
		 * disable EV_READ on our bev and enable write_callback on remote bev.
		 * We enable EV_READ again when all data on remote socket buffer are written,
		 * this is done in write_callback() when remote socket write event is triggered.
		*/
		if (evbuffer_get_length(bufferevent_get_output(bev_remote)) >= OUTPUT_BUFFER_LIMIT) {
			bufferevent_disable(bev, EV_READ);
			bufferevent_setcb(bev_remote, read_callback, write_callback, event_callback, (void *)bev_arg->remote);
		}
	} else {
		/* remote socket is closed, free self */
		bev_arg->listener->nr_conn--;

		bufferevent_free(bev);
		free(bev_arg);
	}
}
int
main ()
{
    int sockfd;
    struct bufferevent *p_event;
    struct sockaddr_in addr;

    ff = fopen("/tmp/log", "w");
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);

    if (inet_pton(AF_INET, SVRADDR, &addr.sin_addr) <= 0) {
        printf("inet_pton");
        exit(1);
    }

    if ((p_base = event_base_new()) == NULL) {
        printf("event_base_new ");
        return 1;
    }

    /* we do not need invoke socket function to create socket */
    if ((p_event = bufferevent_socket_new(p_base, -1, BEV_OPT_CLOSE_ON_FREE)) == NULL) {
        printf("bufferevent_socket_new ");
        return 1;
    }

    /* client actually connecte to server at this time. */
    if ((sockfd = bufferevent_socket_connect(p_event, (struct sockaddr *) &addr,
                                             sizeof(addr))) < 0) {
        printf("bufferevent_socket_connect ");
        return 1;
    }

    /* EV_WRITE is default enabled, EV_READ is default disabled */
    /* So If we disable READ, evbuffer callback will not be added to base (read and write) */
    bufferevent_setcb(p_event, buff_input_cb, NULL, eventcb, p_base);
    bufferevent_enable(p_event, EV_WRITE);

    /* edge-triggered */
    /* default read low-water  mark is 0. */
    /* default read high-water mark is unlimited. */

    /* If the underlying data received over 20, remove the READ event from base */
    bufferevent_setwatermark(p_event, EV_READ, 10, 20);

    event_base_dispatch(p_base);

    return 0;
}
Esempio n. 20
0
static void pending_read(struct bufferevent *bev, void *pending_ptr) {
  struct evwspendingconn* pending = (struct evwspendingconn *)pending_ptr;
  struct evbuffer* input = bufferevent_get_input(pending->bev);
  struct evbuffer_ptr end = evbuffer_search(input, "\r\n\r\n", 4, NULL);
  size_t len = evbuffer_get_length(input);

  if (end.pos == -1) {
    if (len > MAX_HTTP_HEADER_SIZE) {
      remove_pending(pending);
      free_pending(pending);
    }
    return; // full request not yet found
  }

  unsigned char* data = evbuffer_pullup(input, len);
  char accept_key[29];

  struct evwsconnlistener* levws = pending->levws;
  const char* subprotocol = NULL;
  if (evaluate_websocket_handshake((char*)data, len,
      levws->supported_subprotocols, accept_key, &subprotocol)) {
    remove_pending(pending);
    free_pending(pending);
    return;
  }

  evbuffer_drain(input, len);

  bufferevent_setcb(pending->bev, NULL, NULL, NULL, pending);

  struct evbuffer* output = bufferevent_get_output(pending->bev);
  evbuffer_add_printf(output,
      "HTTP/1.1 101 Switching Protocols\r\n"
      "Upgrade: websocket\r\n"
      "Connection: Upgrade\r\n"
      "Sec-WebSocket-Accept: %s\r\n", accept_key);

  if (subprotocol != NULL) {
    evbuffer_add_printf(output, "Sec-WebSocket-Protocol: %s\r\n\r\n",
        subprotocol);
  } else {
    evbuffer_add_printf(output, "\r\n");
  }

  remove_pending(pending);
  struct evwsconn *wsconn = evwsconn_new(pending->bev, subprotocol);
  pending->bev = NULL;
  levws->cb(levws, wsconn, pending->address, pending->socklen,
      levws->user_data);
  free_pending(pending);
}
Esempio n. 21
0
static int create_control_socket_event(struct event_base * base, control_thread_context_t * context, struct bufferevent ** control_event)
{
    struct bufferevent * new_event = NULL;
    int sock_fd = -1;
    struct timeval read_timeout = { 0 };

    /* Get the connection's socket */
    if (IDEVICE_E_SUCCESS != idevice_connection_get_fd(context->control_connection, &sock_fd)) {
        error("ERROR: Failed to get the socket for the reverse proxy's control connection\n");
        goto cleanup;
    }

    /* libevent needs sockets to be non-blocking */
    if (0 != evutil_make_socket_nonblocking(sock_fd)) {
        error("ERROR: Failed to make the reverse proxy's control socket non-blocking\n");
        goto cleanup;
    }

    /* Create a new bufferevent for the control socket */
    new_event = bufferevent_socket_new(base, sock_fd, 0);
    if (NULL == new_event) {
        error("ERROR: Failed to initialize the reverse proxy's control socket\n");
        goto cleanup;
    }

    /* Init the new bufferevent */
    bufferevent_setcb(new_event, rproxy_control_read_cb, NULL, rproxy_control_event_cb, (void*)context);
    read_timeout.tv_sec = CONTROL_RECV_TIMEOUT;
    read_timeout.tv_usec = 0;
    bufferevent_set_timeouts(new_event, &read_timeout, NULL);

    /* Each control message is a 32bit unsigned int, so tell libevent to call
     * our read callback only when there is enough data */
    bufferevent_setwatermark(new_event, EV_READ, sizeof(uint32_t), 0);

    /* Enable both read & write events */
    if (0 != bufferevent_enable(new_event, EV_READ | EV_WRITE)) {
        error("ERROR: Failed to enable the proxy's control socket\n");
        goto cleanup;
    }

    *control_event = new_event;
    return 0;

cleanup:
    if (new_event) {
        bufferevent_free(new_event);
    }

    return -1;
}
Esempio n. 22
0
static struct bufferevent* 
connect_to_proposer(struct event_base* b, struct sockaddr* addr)
{
	struct bufferevent* bev;
	
	bev = bufferevent_socket_new(b, -1, BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev, NULL, NULL, event_callback, NULL);
	if (bufferevent_socket_connect(bev, addr, sizeof(struct sockaddr)) < 0) {
		bufferevent_free(bev);
		return NULL;
	}
	event_base_dispatch(b);
	return bev;
}
Esempio n. 23
0
 void CTcpHandler::TcpAdd(CCommand *pCmd)
 {
     CTcpAddCommand *pConnectCmd = dynamic_cast<CTcpAddCommand *>(pCmd);
     CEventThread *pThread = dynamic_cast<CEventThread *>(GetThread()); 
     m_pBufevt = bufferevent_socket_new(pThread->GetEventBase(), 
             pConnectCmd->m_iFd, BEV_OPT_THREADSAFE);
     bufferevent_setcb(m_pBufevt, CNetThread::OnStaticRead, CNetThread::OnStaticWrite, CNetThread::OnStaticError, this);
     bufferevent_enable(m_pBufevt, EV_READ|EV_PERSIST|EV_ET);		
     bufferevent_setwatermark(m_pBufevt, EV_READ, 
                               OnRead(NULL, 0), 0);
     OnConnect();
     //告诉listen线程
     SetTimeout();
 }
Esempio n. 24
0
void NFCNet::listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data)
{
    //怕你们重了
    NFCNet* pNet = (NFCNet*)user_data;
    bool bClose = pNet->CloseNetObject(fd);
    if (bClose)
    {
        //error
        return;
    }

    if (pNet->mmObject.size() >= pNet->mnMaxConnect)
    {
        //应该T掉,拒绝
        return;
    }

    struct event_base *base = pNet->base;
    //创建一个基于socket的bufferevent
    struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if (!bev)
    {
        //应该T掉,拒绝
        fprintf(stderr, "Error constructing bufferevent!");
        //event_base_loopbreak(base);
        return;
    }

    //我获得一个新连接。为其创建一个bufferevent--FD需要管理
    struct sockaddr_in* pSin = (sockaddr_in*)sa;

    NetObject* pObject = new NetObject(pNet, fd, *pSin, bev);
    pObject->GetNet()->AddNetObject(fd, pObject);

    //为bufferevent设置各种回调
    bufferevent_setcb(bev, conn_readcb, conn_writecb, conn_eventcb, (void*)pObject);

    //开启bufferevent的读写
    bufferevent_enable(bev, EV_READ|EV_WRITE);

    //模拟客户端已连接事件
    conn_eventcb(bev, BEV_EVENT_CONNECTED, (void*)pObject);
    //////////////////////////////////////////////////////////////////////////

    struct timeval tv;
    /* 设置读超时120秒, 可做为心跳机制, 120秒没收到消息就T */
    tv.tv_sec = 120;
    tv.tv_usec = 0;
    bufferevent_set_timeouts(bev, &tv, NULL);
}
Esempio n. 25
0
struct bufferevent *
bufferevent_new(evutil_socket_t fd,
    bufferevent_data_cb readcb, bufferevent_data_cb writecb,
    bufferevent_event_cb eventcb, void *cbarg)
{
	struct bufferevent *bufev;

	if (!(bufev = bufferevent_socket_new(NULL, fd, 0)))
		return NULL;

	bufferevent_setcb(bufev, readcb, writecb, eventcb, cbarg);

	return bufev;
}
Esempio n. 26
0
static void on_accept(struct evconnlistener* l, evutil_socket_t* fd, struct sockaddr* addr, int socklen, void *arg)
{
	struct tcp_receiver* r = arg;
	struct event_base* b = evconnlistener_get_base(l);
	struct bufferevent *bev = bufferevent_socket_new(b, fd, BEV_OPT_CLOSE_ON_FREE);
	/*设置读事件函数和错误函数*/
	bufferevent_setcb(bev, on_read, NULL, on_error, arg);
	/*设置监视的socket事件*/
	bufferevent_enable(bev, EV_READ|EV_WRITE);
	/*添加到事件管理器中*/
	carray_push_back(r->bevs, bev);

	paxos_log_info("Accepted connection from %s:%d", inet_ntoa(((struct sockaddr_in*)addr)->sin_addr), ntohs(((struct sockaddr_in*)addr)->sin_port));
}
Esempio n. 27
0
/* Open a client socket to connect to localhost on sin */
static void
start_client(struct event_base *base)
{
	struct bufferevent *bev = bufferevent_socket_new(base, -1,
                                                         BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev, client_read_cb, NULL, client_event_cb, NULL);

	if (bufferevent_socket_connect(bev, (struct sockaddr *)&saddr,
                                       sizeof(saddr)) < 0) {
		my_perror("Could not connect!");
		bufferevent_free(bev);
		exit(2);
	}
}
Esempio n. 28
0
static void
socks_accept(struct evconnlistener *evl, evutil_socket_t new_fd,
			struct sockaddr *addr, int socklen, void *ctx)
{
	struct event_base *base = evconnlistener_get_base(evl);
	struct bufferevent *bev;

	LWIP_DEBUGF(SOCKS_DEBUG, ("%s: Accepting socks connection\n", __func__));

	bev = bufferevent_socket_new(base, new_fd, BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(bev, socks_version, NULL, socks_error, ctx);
	bufferevent_setwatermark(bev, EV_READ, 1, 2048);
	bufferevent_enable(bev, EV_READ|EV_WRITE);
}
Esempio n. 29
0
void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data)
{
    struct event_base *base = (event_base*)user_data;
    struct bufferevent *bev;

    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if (!bev) {
        std::cout << "Error constructing bufferevent!\n";
        event_base_loopbreak(base);
        return;
    }
    bufferevent_setcb(bev, conn_readcb, NULL, conn_eventcb, NULL);
    int res = bufferevent_enable(bev, EV_READ);
}
Esempio n. 30
0
// socket事件
int jmm_init_event_sock(int idx, int sfd)
{
    if(event_wf.sock[idx] != NULL){
        return JMM_FAIL;
    }
    event_wf.sock[idx] = bufferevent_socket_new(event_wf.base, sfd,
            BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(event_wf.sock[idx], jmm_sock_read_wf_cb, jmm_sock_write_wf_cb,
            jmm_sock_event_wf_cb, (void*)idx);
    bufferevent_enable(event_wf.sock[idx], EV_WRITE);
    bufferevent_enable(event_wf.sock[idx], EV_READ);

    return JMM_SUCCESS;
}