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; }
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; }