static int ptcp_open(struct protocol_ctx *sc, const char *url) { struct ptcp_ctx *c = sc->priv; int len; char *p; char *tag = ":"; p = strstr(url, tag); if (!p) { printf("ptcp url is invalid\n"); return -1; } len = p - url; strncpy(c->src_ip, url, len); p += strlen(tag); c->src_port = atoi(p); ptcp_socket_t *ps = ptcp_socket(); if (ps == NULL) { printf("error!\n"); return -1; } c->ps = ps; struct sockaddr_in si; si.sin_family = AF_INET; si.sin_addr.s_addr = inet_addr(c->src_ip); si.sin_port = htons(c->src_port); ptcp_bind(ps, (struct sockaddr*)&si, sizeof(si)); printf("url: \"ptcp://%s:%d\"\n", c->src_ip, c->src_port); ptcp_listen(ps, 0); return 0; }
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; }
//=================ptcp======================= void *ptcp_server_init(const char *host, uint16_t port) { ptcp_socket_t *ps = ptcp_socket(); if (ps == NULL) { printf("error!\n"); return NULL; } struct sockaddr_in si; si.sin_family = AF_INET; si.sin_addr.s_addr = host ? inet_addr(host) : INADDR_ANY; si.sin_port = htons(port); ptcp_bind(ps, (struct sockaddr*)&si, sizeof(si)); ptcp_listen(ps, 0); return ps; }
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); }