struct rpc *rpc_create(const char *host, uint16_t port) { int ret; char str_ip[INET_ADDRSTRLEN]; struct skt_connection *sc; struct rpc *r = CALLOC(1, struct rpc); if (!r) { loge("malloc failed!\n"); return NULL; } sc = skt_tcp_connect(host, port); if (sc == NULL) { loge("connect failed!\n"); return NULL; } r->fd = sc->fd; if (-1 == skt_set_noblk(sc->fd, 0)) { loge("block skt_recv failed!\n"); } ret = rpc_recv(r, r->packet.header.uuid_src, MAX_UUID_LEN); if (ret != MAX_UUID_LEN) { loge("rpc_recv failed: ret = %d\n", ret); } // if (-1 == skt_set_noblk(sc->fd, 1)) { // loge("no-block skt_recv failed!\n"); // } skt_addr_ntop(str_ip, sc->local.ip); logi("local addr = %s:%d, uuid_src = %s\n", str_ip, sc->local.port, r->packet.header.uuid_src); skt_addr_ntop(str_ip, sc->remote.ip); //logd("remote ip = %s, port = %d\n", str_ip, sc->remote.port); r->evbase = gevent_base_create(); return r; }
static int on_peer_post_msg_resp(struct rpc *r, void *arg, int len) { pthread_t tid; struct p2p *p2p = _p2p; uint32_t peer_id; char localip[MAX_ADDR_STRING]; char reflectip[MAX_ADDR_STRING]; struct sockaddr_in si; logi("on_peer_post_msg_resp len = %d\n", len); struct nat_info *nat = (struct nat_info *)arg; logi("get nat info from peer\n"); logi("nat.uuid = 0x%08x\n", nat->uuid); skt_addr_ntop(localip, nat->local.ip); skt_addr_ntop(reflectip, nat->reflect.ip); logi("nat.type = %d\n", nat->type); logi("nat.local_addr %s:%d\n", localip, nat->local.port); logi("nat.reflect_addr %s:%d\n", reflectip, nat->reflect.port); p2p->ps = ptcp_socket_by_fd(p2p->nat.fd); if (p2p->ps == NULL) { loge("error!\n"); return -1; } if (p2p->rpc_state == P2P_RPC_SYN_SENT) {//client logi("as p2p client\n"); sleep(1); if (_p2p_connect(p2p, localip, nat->local.port)) { loge("_p2p_connect nat.local failed, try nat.reflect\n"); if (_p2p_connect(p2p, reflectip, nat->reflect.port)) { logi("_p2p_connect nat.reflect failed too\n"); return -1; } } return 0; } //server logi("as p2p server\n"); peer_id = nat->uuid; p2p_connect(p2p, peer_id); si.sin_family = AF_INET; si.sin_addr.s_addr = inet_addr(_local_ip); si.sin_port = htons(_local_port); logi("ptcp_bind %s:%d\n", _local_ip, _local_port); ptcp_bind(p2p->ps, (struct sockaddr*)&si, sizeof(si)); ptcp_listen(p2p->ps, 0); pthread_create(&tid, NULL, tmp_thread, p2p); return 0; }
struct rpc *rpc_connect_create(struct rpcd *rpcd, int fd, uint32_t ip, uint16_t port) { char str_ip[INET_ADDRSTRLEN]; char uuid[MAX_UUID_LEN]; int ret; struct rpc *r = (struct rpc *)calloc(1, sizeof(struct rpc)); if (!r) { loge("malloc failed!\n"); return NULL; } r->fd = fd; create_uuid(uuid, MAX_UUID_LEN, fd, ip, port); struct gevent *e = gevent_create(fd, on_recv, NULL, on_error, (void *)r); if (-1 == gevent_add(rpcd->evbase, e)) { loge("event_add failed!\n"); } r->ev = e; rpc_header_format(r, uuid, uuid, 0, 0); ret = rpc_send(r, uuid, MAX_UUID_LEN); if (ret != MAX_UUID_LEN) { loge("rpc_send failed!\n"); } rpcd_connect_add(rpcd, r, fd, uuid); skt_addr_ntop(str_ip, ip); logi("on_connect fd = %d, remote_addr = %s:%d, uuid=%s\n", fd, str_ip, port, uuid); return r; }
void on_rpc_read(int fd, void *arg) { pthread_t tid; struct p2p *p2p = (struct p2p *)arg; struct rpc *r = p2p->rpc; char *peer_id; char localip[MAX_ADDR_STRING]; char reflectip[MAX_ADDR_STRING]; struct sockaddr_in si; struct iobuf *buf = rpc_recv_buf(r); if (!buf) { printf("rpc_recv_buf failed!\n"); return; } struct nat_info *nat = (struct nat_info *)buf->addr; printf("peer info\n"); printf("nat.uuid = %s\n", nat->uuid); skt_addr_ntop(localip, nat->local.ip); skt_addr_ntop(reflectip, nat->reflect.ip); printf("nat.type = %d, local.ip = %s, port = %d\n", nat->type, localip, nat->local.port); printf("reflect.ip = %s, port = %d\n", reflectip, nat->reflect.port); p2p->ps = ptcp_socket_by_fd(p2p->nat.fd); if (p2p->ps == NULL) { printf("error!\n"); return; } if (p2p->rpc_state == P2P_RPC_SYN_SENT) {//client sleep(1); _p2p_connect(p2p, reflectip, nat->reflect.port); return; } //server peer_id = nat->uuid; p2p_connect(p2p, peer_id); si.sin_family = AF_INET; si.sin_addr.s_addr = inet_addr(_local_ip); si.sin_port = htons(_local_port); printf("ptcp_bind %s:%d\n", _local_ip, _local_port); ptcp_bind(p2p->ps, (struct sockaddr*)&si, sizeof(si)); ptcp_listen(p2p->ps, 0); pthread_create(&tid, NULL, tmp_thread, p2p); }
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; }
struct rpc *rpc_create(const char *host, uint16_t port) { char local_ip[INET_ADDRSTRLEN]; char remote_ip[INET_ADDRSTRLEN]; struct rpc *r = CALLOC(1, struct rpc); if (!r) { loge("malloc failed!\n"); return NULL; } memset(&r->recv_pkt, 0, sizeof(struct rpc_packet)); struct skt_connection *connect; connect = skt_tcp_connect(host, port); if (!connect) { loge("connect failed!\n"); return NULL; } r->fd = connect->fd; if (-1 == skt_set_block(r->fd)) { loge("skt_set_block failed!\n"); } r->evbase = gevent_base_create(); if (!r->evbase) { loge("gevent_base_create failed!\n"); return NULL; } rpc_set_cb(r, on_read, on_write, on_error, r); r->dispatch_thread = thread_create("rpc_dispatch", rpc_dispatch_thread, r); r->state = rpc_inited; if (thread_sem_wait(r->dispatch_thread, 2000) == -1) { loge("wait response failed %d:%s\n", errno, strerror(errno)); return NULL; } skt_addr_ntop(local_ip, connect->local.ip); skt_addr_ntop(remote_ip, connect->remote.ip); logi("rpc[%08x] connect information:\n", r->send_pkt.header.uuid_src); logi("local addr = %s:%d\n", local_ip, connect->local.port); logi("remote addr = %s:%d\n", remote_ip, connect->remote.port); return r; }
static int udp_open(struct protocol_ctx *sc, const char *url) { struct udp_ctx *c = sc->priv; struct skt_addr addr; skt_addr_list_t *tmp; char str[MAX_ADDR_STRING]; int len; char *p; char *tag = ":"; p = strstr(url, tag); if (!p) { printf("udp url is invalid\n"); return -1; } len = p - url;//"127.0.0.1:2333" printf("url = %s, len = %d\n", url, len); strncpy(c->dst_ip, url, len); p += strlen(tag); c->dst_port = atoi(p); if (0 == skt_get_local_list(&tmp, 0)) { for (; tmp; tmp = tmp->next) { skt_addr_ntop(str, tmp->addr.ip); printf("ip = %s port = %d\n", str, tmp->addr.port); } } strcpy(c->src_ip, str); c->fd = skt_udp_bind(str, c->dst_port, 0); if (c->fd == -1) { printf("bind %s failed\n", str); return -1; } printf("bind fd = %d\n", c->fd); sc->fd = c->fd; skt_get_addr_by_fd(&addr, c->fd); c->src_port = addr.port; // skt_set_noblk(c->fd, 1); // skt_set_reuse(c->fd, 1); printf("url: \"udp://%s:%d?localport=%d\"\n", c->src_ip, c->src_port, c->dst_port); return 0; }