Exemplo n.º 1
0
static int
test_rbt_gen(char *filename, char *command, char *testname,
	     isc_result_t exp_result)
{
	int		rval;
	int		result;
	dns_rbt_t	*rbt;
	isc_result_t	isc_result;
	isc_result_t	dns_result;
	isc_mem_t	*mctx;
	isc_entropy_t	*ectx;
	dns_name_t	*dns_name;

	result = T_UNRESOLVED;

	if (strcmp(command, "create") != 0)
		t_info("testing using name %s\n", testname);

	mctx = NULL;
	ectx = NULL;

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	rbt = NULL;
	if (rbt_init(filename, &rbt, mctx) != 0) {
		if (strcmp(command, "create") == 0)
			result = T_FAIL;
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	/*
	 * Now try the database command.
	 */
	if (strcmp(command, "create") == 0) {
		result = T_PASS;
	} else if (strcmp(command, "add") == 0) {
		if (create_name(testname, mctx, &dns_name) == 0) {
			dns_result = dns_rbt_addname(rbt, dns_name, dns_name);

			if (dns_result != ISC_R_SUCCESS)
				delete_name(dns_name, mctx);

			if (dns_result == exp_result) {
				if (dns_result == ISC_R_SUCCESS) {
					rval = t1_search(testname, rbt, mctx,
							 &dns_result);
					if (rval == 0) {
					     if (dns_result == ISC_R_SUCCESS) {
						     result = T_PASS;
					     } else {
						     result = T_FAIL;
					     }
					} else {
						t_info("t1_search failed\n");
						result = T_UNRESOLVED;
					}
				} else {
					result = T_PASS;
				}
			} else {
				t_info("dns_rbt_addname returned %s, "
				       "expected %s\n",
				       dns_result_totext(dns_result),
				       dns_result_totext(exp_result));
				result = T_FAIL;
			}
		} else {
			t_info("create_name failed\n");
			result = T_UNRESOLVED;
		}
	} else if ((strcmp(command, "delete") == 0) ||
		   (strcmp(command, "nuke") == 0)) {
		rval = t1_delete(testname, rbt, mctx, &dns_result);
		if (rval == 0) {
			if (dns_result == exp_result) {
				rval = t1_search(testname, rbt, mctx,
						 &dns_result);
				if (rval == 0) {
					if (dns_result == ISC_R_SUCCESS) {
						t_info("dns_rbt_deletename "
						       "didn't delete "
						       "the name");
						result = T_FAIL;
					} else {
						result = T_PASS;
					}
				}
			} else {
				t_info("delete returned %s, expected %s\n",
					dns_result_totext(dns_result),
					dns_result_totext(exp_result));
				result = T_FAIL;
			}
		}
	} else if (strcmp(command, "search") == 0) {
		rval = t1_search(testname, rbt, mctx, &dns_result);
		if (rval == 0) {
			if (dns_result == exp_result) {
				result = T_PASS;
			} else {
				t_info("find returned %s, expected %s\n",
					dns_result_totext(dns_result),
					dns_result_totext(exp_result));
				result = T_FAIL;
			}
		}
	}

	dns_rbt_destroy(&rbt);
	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);
	return(result);
}
Exemplo n.º 2
0
static int
t_dns_rbtnodechain_init(char *dbfile, char *findname,
			char *nextname, char *nextorigin,
			char *prevname, char *prevorigin,
			char *firstname, char *firstorigin,
			char *lastname, char *lastorigin)
{
	int			result;
	int			len;
	int			nfails;
	dns_rbt_t		*rbt;
	dns_rbtnode_t		*node;
	dns_rbtnodechain_t	chain;
	isc_mem_t		*mctx;
	isc_entropy_t		*ectx;
	isc_result_t		isc_result;
	isc_result_t		dns_result;
	dns_fixedname_t		dns_findname;
	dns_fixedname_t		dns_foundname;
	dns_fixedname_t		dns_firstname;
	dns_fixedname_t		dns_lastname;
	dns_fixedname_t		dns_prevname;
	dns_fixedname_t		dns_nextname;
	dns_fixedname_t		dns_origin;
	isc_buffer_t		isc_buffer;

	result = T_UNRESOLVED;

	nfails = 0;
	mctx = NULL;
	ectx = NULL;

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(result);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_rbtnodechain_init(&chain, mctx);

	rbt = NULL;
	if (rbt_init(dbfile, &rbt, mctx)) {
		t_info("rbt_init %s failed\n", dbfile);
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	len = strlen(findname);
	isc_buffer_init(&isc_buffer, findname, len);
	isc_buffer_add(&isc_buffer, len);

	dns_fixedname_init(&dns_foundname);
	dns_fixedname_init(&dns_findname);
	dns_fixedname_init(&dns_firstname);
	dns_fixedname_init(&dns_origin);
	dns_fixedname_init(&dns_lastname);
	dns_fixedname_init(&dns_prevname);
	dns_fixedname_init(&dns_nextname);

	dns_result = dns_name_fromtext(dns_fixedname_name(&dns_findname),
					&isc_buffer, NULL, 0, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_name_fromtext failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Set the starting node.
	 */
	node = NULL;
	dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname),
				      dns_fixedname_name(&dns_foundname),
				      &node, &chain, DNS_RBTFIND_EMPTYDATA,
				      NULL, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("dns_rbt_findnode failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Check next.
	 */
	t_info("checking for next name of %s and new origin of %s\n",
	       nextname, nextorigin);
	dns_result = dns_rbtnodechain_next(&chain,
					   dns_fixedname_name(&dns_nextname),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_next unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}

	nfails += t_namechk(dns_result, &dns_nextname, nextname, &dns_origin,
			    nextorigin, DNS_R_NEWORIGIN);

	/*
	 * Set the starting node again.
	 */
	node = NULL;
	dns_fixedname_init(&dns_foundname);
	dns_result = dns_rbt_findnode(rbt, dns_fixedname_name(&dns_findname),
				      dns_fixedname_name(&dns_foundname),
				      &node, &chain, DNS_RBTFIND_EMPTYDATA,
				      NULL, NULL);

	if (dns_result != ISC_R_SUCCESS) {
		t_info("\tdns_rbt_findnode failed %s\n",
		       dns_result_totext(dns_result));
		return(result);
	}

	/*
	 * Check previous.
	 */
	t_info("checking for previous name of %s and new origin of %s\n",
	       prevname, prevorigin);
	dns_fixedname_init(&dns_origin);
	dns_result = dns_rbtnodechain_prev(&chain,
					   dns_fixedname_name(&dns_prevname),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_prevname, prevname, &dns_origin,
			    prevorigin, DNS_R_NEWORIGIN);

	/*
	 * Check first.
	 */
	t_info("checking for first name of %s and new origin of %s\n",
	       firstname, firstorigin);
	dns_result = dns_rbtnodechain_first(&chain, rbt,
					    dns_fixedname_name(&dns_firstname),
					    dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_first unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_firstname, firstname,
			    &dns_origin, firstorigin, DNS_R_NEWORIGIN);

	/*
	 * Check last.
	 */
	t_info("checking for last name of %s\n", lastname);
	dns_result = dns_rbtnodechain_last(&chain, rbt,
					   dns_fixedname_name(&dns_lastname),
					   dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_lastname, lastname, &dns_origin,
			    lastorigin, DNS_R_NEWORIGIN);

	/*
	 * Check node ordering.
	 */
	t_info("checking node ordering\n");
	nfails += t9_walkchain(&chain, rbt);

	if (nfails)
		result = T_FAIL;
	else
		result = T_PASS;

	dns_rbtnodechain_invalidate(&chain);
	dns_rbt_destroy(&rbt);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);

	return(result);
}
Exemplo n.º 3
0
static int
t_dns_rbtnodechain_last(char *dbfile, char *expected_lastname,
			char *expected_lastorigin,
			char *expected_prevname,
			char *expected_prevorigin)
{

	int			result;
	int			nfails;
	dns_rbt_t		*rbt;
	dns_rbtnodechain_t	chain;
	isc_mem_t		*mctx;
	isc_entropy_t		*ectx;
	isc_result_t		isc_result;
	isc_result_t		dns_result;
	dns_fixedname_t		dns_name;
	dns_fixedname_t		dns_origin;
	isc_result_t		expected_result;

	result = T_UNRESOLVED;

	nfails = 0;
	mctx = NULL;
	ectx = NULL;

	dns_fixedname_init(&dns_name);
	dns_fixedname_init(&dns_origin);

	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(result);
	}

	isc_result = isc_entropy_create(mctx, &ectx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_entropy_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_hash_create: %s: exiting\n",
		       dns_result_totext(isc_result));
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	dns_rbtnodechain_init(&chain, mctx);

	rbt = NULL;
	if (rbt_init(dbfile, &rbt, mctx)) {
		t_info("rbt_init %s failed\n", dbfile);
		isc_hash_destroy();
		isc_entropy_detach(&ectx);
		isc_mem_destroy(&mctx);
		return(result);
	}

	t_info("testing for last name of %s, origin of %s\n",
	       expected_lastname, expected_lastorigin);

	dns_result = dns_rbtnodechain_last(&chain, rbt,
					   dns_fixedname_name(&dns_name),
					   dns_fixedname_name(&dns_origin));

	if (dns_result != DNS_R_NEWORIGIN) {
		t_info("dns_rbtnodechain_last unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	nfails += t_namechk(dns_result, &dns_name, expected_lastname,
			    &dns_origin, expected_lastorigin, DNS_R_NEWORIGIN);

	t_info("testing for previous name of %s, origin of %s\n",
	       expected_prevname, expected_prevorigin);

	dns_fixedname_init(&dns_name);
	dns_result = dns_rbtnodechain_prev(&chain,
					   dns_fixedname_name(&dns_name),
					   dns_fixedname_name(&dns_origin));

	if ((dns_result != ISC_R_SUCCESS) &&
	    (dns_result != DNS_R_NEWORIGIN)) {
		t_info("dns_rbtnodechain_prev unexpectedly returned %s\n",
		       dns_result_totext(dns_result));
	}
	if (strcasecmp(expected_lastorigin, expected_prevorigin) == 0)
		expected_result = ISC_R_SUCCESS;
	else
		expected_result = DNS_R_NEWORIGIN;
	nfails += t_namechk(dns_result, &dns_name, expected_prevname,
			    &dns_origin, expected_prevorigin, expected_result);

	if (nfails)
		result = T_FAIL;
	else
		result = T_PASS;

	dns_rbtnodechain_invalidate(&chain);
	dns_rbt_destroy(&rbt);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);
	isc_mem_destroy(&mctx);

	return(result);
}
Exemplo n.º 4
0
RBT_ROOT *rbtsimple_new_tree( rbt_compare_keys_fn compare_keys ,
                              uint32 key_length , /*@null@*/ void *data )
{
  return rbt_init( data , rbtsimple_alloc , rbtsimple_free ,
                   compare_keys , key_length , 0 ) ;
}
Exemplo n.º 5
0
int su_serv_create(su_serv_t *psvr, const SA *saddr, socklen_t servlen, int nthread)
{
    if (nthread <= 0) {
        errno = EINVAL;
        return -1;
    }
    psvr->fd = socket(saddr->sa_family, SOCK_DGRAM, 0);
    if (psvr->fd < 0) {
        err_ret("serv %x create failed, socket error", psvr);
        return -1;
    }
    if (bind(psvr->fd, saddr, servlen) < 0) {
        close(psvr->fd);
        psvr->fd = -1;
        return -1;
    }
    if (setfd_nonblock(psvr->fd) < 0) {
        close(psvr->fd);
        psvr->fd = -1;
        return -1;
    }

    memset(&psvr->servaddr, 0, sizeof(SAUN));
    memcpy(&psvr->servaddr, saddr, servlen);
    psvr->servlen = servlen;

    psvr->seq = 0;
    psvr->rttinit = 0;
    psvr->retry = RTT_MAXNREXMT;

    psvr->ackwaitnum = 0;
    list_init(&psvr->ackrecvls);
    list_init(&psvr->synrecvls);
    list_init(&psvr->lsackcache);
    rbt_init(&psvr->rbackcache, cache_getkey, search_cache_cmp);

    pthread_mutex_init(&psvr->mutex, 0);
    pthread_mutex_init(&psvr->lock, 0);
    pthread_cond_init(&psvr->ackcond, 0);
    pthread_cond_init(&psvr->syncond, 0);
    pthread_mutex_init(&psvr->cachelock, 0);

    if (su_serv_thread_install(psvr, nthread) < 0) {
        pthread_mutex_destroy(&psvr->mutex);
        pthread_mutex_destroy(&psvr->lock);
        pthread_mutex_destroy(&psvr->cachelock);
        pthread_cond_destroy(&psvr->ackcond);
        pthread_cond_destroy(&psvr->syncond);
        close(psvr->fd);
        psvr->fd = -1;
        return -1;
    }

    pthread_mutex_lock(&emutex);
    if (sugem == 0) {
        sugem = Em_open(100, -1, 0, 0, 0);
        Em_run(sugem);

        struct timeval now;
        gettimeofday(&now, 0);
        srand(now.tv_sec % 1000 + now.tv_usec);
    }
    psvr->sid = rand() % 65535;
    pthread_mutex_unlock(&emutex);

    memset(&psvr->fe, 0, sizeof(fe_t));
    fe_init(&psvr->fe, sugem, psvr->fd);
    fe_set(&psvr->fe, EPOLLIN, handle_su_serv_recv);
    fe_set(&psvr->fe, EPOLLET, 0);
    Fe_em_add(&psvr->fe);

    return psvr->fd;
}
Exemplo n.º 6
0
/* Initialize the page allocator, return 1 on success, 0 otherwise. */
int
lm_init_page_alloc(lm_chunk_t* chunk, ljmm_opt_t* mm_opt) {
    if (!chunk) {
        /* Trunk is not yet allocated */
        return 0;
    }

    if (alloc_info) {
        /* This function was succesfully invoked before */
        return 1;
    }

    int page_num = chunk->page_num;
    if (unlikely(mm_opt != NULL)) {
        int pn = mm_opt->dbg_alloc_page_num;
        if (((pn > 0) && (pn > page_num)) || !pn)
            return 0;
        else if (pn > 0) {
            page_num = pn;
        }

        if (!bc_set_parameter(mm_opt->enable_block_cache,
                              mm_opt->blk_cache_in_page)) {
            return 0;
        }
    }

    int alloc_sz = sizeof(lm_alloc_t) +
                   sizeof(lm_page_t) * (page_num + 1);

    alloc_info = (lm_alloc_t*) MYMALLOC(alloc_sz);
    if (!alloc_info) {
        errno = ENOMEM;
        return 0;
    }

    alloc_info->first_page = chunk->base;
    alloc_info->page_num   = page_num;
    alloc_info->page_size  = chunk->page_size;
    alloc_info->page_size_log2 = log2_int32(chunk->page_size);

    /* Init the page-info */
    char* p =  (char*)(alloc_info + 1);
    int align = __alignof__(lm_page_t);
    p = (char*)((((intptr_t)p) + align - 1) & ~align);
    alloc_info->page_info = (lm_page_t*)p;

    int i;
    lm_page_t* pi = alloc_info->page_info;
    for (i = 0; i < page_num; i++) {
        pi[i].order = INVALID_ORDER;
        pi[i].flags = 0;
    }

    /* Init the buddy allocator */
    int e;
    rb_tree_t* free_blks = &alloc_info->free_blks[0];
    for (i = 0, e = MAX_ORDER; i < e; i++)
        rbt_init(&free_blks[i]);
    rbt_init(&alloc_info->alloc_blks);

    /* Determine the max order */
    int max_order = 0;
    unsigned int bitmask;
    for (bitmask = 0x80000000/*2G*/, max_order = 31;
         bitmask;
         bitmask >>= 1, max_order --) {
        if (bitmask & page_num)
            break;
    }
    alloc_info->max_order = max_order;

    /* So, the ID of biggest block's first page is "1 << order". e.g.
     * Suppose the chunk contains 11 pages, which will be divided into 3
     * blocks, eaching containing 1, 2 and 8 pages. The indices of these
     * blocks are 0, 1, 3 respectively, and their IDs are 5, 6, and 8
     * respectively. In this case:
     *    alloc_info->idx_2_id_adj == 5 == page_id(*) - page_idx(*)
     */
    int idx_2_id_adj = (1 << max_order) - (page_num & ((1 << max_order) - 1));
    alloc_info->idx_2_id_adj = idx_2_id_adj;

    /* Divide the chunk into blocks, smaller block first. Smaller blocks
     * are likely allocated and deallocated frequently. Therefore, they are
     * better off residing closer to data segment.
     */
    int page_idx = 0;
    int order = 0;
    for (bitmask = 1, order = 0;
         bitmask != 0;
         bitmask = bitmask << 1, order++) {
        if (page_num & bitmask) {
            add_free_block(page_idx, order);
            page_idx += (1 << order);
        }
    }

    /*init the block cache */
    bc_init();

    return 1;
}
Exemplo n.º 7
0
int su_peer_create_bind(su_peer_t *psar, int port, const SA *destaddr, socklen_t destlen)
{
    psar->fd = socket(destaddr->sa_family, SOCK_DGRAM, 0);
    if (psar->fd < 0) {
        err_ret("peer %x create failed, socket error", psar);
        return -1;
    }

    if (port > 0 && port <= 65535) {
        void *paddr;
        SA4 s4;
        SA6 s6;
        switch (destaddr->sa_family) {
            case PF_INET:
                memcpy(&s4, destaddr, destlen);  /* for sin_family and more... */
                s4.sin_port = htons(port);
                inet_pton(PF_INET, "0.0.0.0", &s4.sin_addr.s_addr);
                paddr = &s4;
                break;
            case PF_INET6:
                memcpy(&s6, destaddr, destlen); /* for sin6_family and more...  */
                s6.sin6_port = htons(port);
                inet_pton(PF_INET6, "::", &s6.sin6_addr.__in6_u);
                paddr = &s6;
                break;
            default:
                close(psar->fd);
                psar->fd = -1;
                errno = EINVAL;
                return -1;
        }
        int reuse = 1;
        if (setsockopt(psar->fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) {
            close(psar->fd);
            psar->fd = -1;
            return -1;
        }
        if (bind(psar->fd, paddr, destlen) < 0) {
            close(psar->fd);
            psar->fd = -1;
            return -1;
        }
    }

    if (setfd_nonblock(psar->fd) < 0) {
        close(psar->fd);
        psar->fd = -1;
        return -1;
    }

    memset(&psar->destaddr, 0, sizeof(SAUN));
    memcpy(&psar->destaddr, destaddr, destlen);
    psar->destlen = destlen;

    psar->seq = 0;
    psar->rttinit = 0;
    psar->retry = RTT_MAXNREXMT;

    psar->ackwaitnum = 0;
    list_init(&psar->ackrecvls);
    list_init(&psar->synrecvls);
    list_init(&psar->lsackcache);
    rbt_init(&psar->rbackcache, cache_getkey, search_cache_cmp);

    psar->nowsynframe = 0;

    pthread_mutex_init(&psar->mutex, 0);
    pthread_mutex_init(&psar->lock, 0);
    pthread_cond_init(&psar->ackcond, 0);
    pthread_cond_init(&psar->syncond, 0);
    pthread_mutex_init(&psar->cachelock, 0);

    if (su_peer_thread_install(psar) < 0) {
        pthread_mutex_destroy(&psar->mutex);
        pthread_mutex_destroy(&psar->lock);
        pthread_cond_destroy(&psar->ackcond);
        pthread_cond_destroy(&psar->syncond);
        pthread_mutex_destroy(&psar->cachelock);

        close(psar->fd);
        psar->fd = -1;
        return -1;
    }

    pthread_mutex_lock(&emutex);
    if (sugem == 0) {
        sugem = Em_open(100, -1, 0, 0, 0);
        Em_run(sugem, 1);

        struct timeval now;
        gettimeofday(&now, 0);
        srand(now.tv_sec % 1000 + now.tv_usec);
    }
    psar->sid = rand() % 65535;
    pthread_mutex_unlock(&emutex);

    memset(&psar->fe, 0, sizeof(fe_t));
    fe_init(&psar->fe, sugem, psar->fd);
    fe_set(&psar->fe, EPOLLIN, handle_su_peer_recv);
    fe_set(&psar->fe, EPOLLET, 0);
    Fe_em_add(&psar->fe);

    return psar->fd;
}