struct p2p *p2p_init(const char *rpc_srv, const char *stun_srv) { char ip[64]; struct skt_addr tmpaddr; static stun_addr _mapped; struct p2p *p2p = CALLOC(1, struct p2p); if (!p2p) { loge("malloc failed: %d\n", errno); return NULL; } p2p->rpc = rpc_create(rpc_srv, _rpc_port); if (!p2p->rpc) { loge("rpc_create failed\n"); return NULL; } RPC_REGISTER_MSG_MAP(BASIC_RPC_API_RESP); rpc_set_cb(p2p->rpc, on_rpc_read, on_rpc_write, on_rpc_error, p2p); skt_getaddr_by_fd(p2p->rpc->fd, &tmpaddr); skt_addr_ntop(_local_ip, tmpaddr.ip); //_local_port = tmpaddr.port; //logi("_local_port = %d\n", _local_port); stun_init(stun_srv); p2p->nat.type = stun_nat_type(); p2p->nat.uuid = p2p->rpc->send_pkt.header.uuid_src; p2p->nat.local.ip = skt_addr_pton(_local_ip); _local_port = random_port(); p2p->nat.local.port = _local_port; p2p->nat.fd = stun_socket(_local_ip, _local_port, &_mapped); _mapped.addr = ntohl(_mapped.addr); skt_addr_ntop(ip, _mapped.addr); p2p->nat.reflect.ip = _mapped.addr; p2p->nat.reflect.port = _mapped.port; logi("get nat info from local\n"); logi("nat.type = %d\n", p2p->nat.type); logi("nat.local_addr %s:%d\n", _local_ip, p2p->nat.local.port); logi("nat.reflect_addr %s:%d\n", ip, p2p->nat.reflect.port); p2p->rpc_state = P2P_RPC_INIT; _p2p = p2p; return p2p; }
static int test(const char *local_ip, uint16_t local_port) { int i; int ret; int epfd, fd; struct in_addr sa; struct sockaddr_in si; socklen_t si_len; struct epoll_event event; struct epoll_event evbuf[MAX_EPOLL_EVENT]; stun_addr mapped; pthread_t tid; struct addr_info args; char ip[64] = {0}; uint16_t port; if (0 == stun_init(stun_server_ip)) { printf("stun init failed!\n"); return -1; } fd = stun_socket(local_ip, local_port, &mapped); if (fd == -1) { printf("stun open socket failed!\n"); return -1; } memset(&si, 0, sizeof(si)); if (-1 == getsockname(fd, (struct sockaddr *)&si, &si_len)) { perror("getsockname failed!\n"); } printf("ip = %s port = %d\n", inet_ntoa(si.sin_addr), ntohs(si.sin_port)); stun_nat_type(); pthread_create(&tid, NULL, keep_alive, (void *)&fd); sa.s_addr = ntohl(mapped.addr); printf("mapped ip = %s, port = %d\n", inet_ntoa(sa), mapped.port); printf("input peer ip: "); scanf("%s", ip); printf("input peer port: "); scanf("%hd", &port); if (-1 == (epfd = epoll_create(1))) { perror("epoll_create"); return -1; } memset(&event, 0, sizeof(event)); event.data.fd = fd; event.events = EPOLLIN | EPOLLET; if (-1 == epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event)) { perror("epoll_ctl"); close(epfd); return -1; } args.fd = fd; args.port = port; strcpy(args.ip, ip); pthread_create(&tid, NULL, send_msg, (void *)&args); while (1) { ret = epoll_wait(epfd, evbuf, MAX_EPOLL_EVENT, -1); if (ret == -1) { perror("epoll_wait"); continue; } for (i = 0; i < ret; i++) { if (evbuf[i].data.fd == -1) continue; if (evbuf[i].events & (EPOLLERR | EPOLLHUP)) { perror("epoll error"); } if (evbuf[i].events & EPOLLOUT) { perror("epoll out"); } if (evbuf[i].events & EPOLLIN) { recv_msg(evbuf[i].data.fd); } } } }