/* * Initialize IP socket address based on the address and port info. */ PJ_DEF(pj_status_t) pj_sockaddr_init(int af, pj_sockaddr *addr, const pj_str_t *cp, pj_uint16_t port) { pj_status_t status; if (af == PJ_AF_INET) { return pj_sockaddr_in_init(&addr->ipv4, cp, port); } /* IPv6 specific */ PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP); pj_bzero(addr, sizeof(pj_sockaddr_in6)); addr->addr.sa_family = PJ_AF_INET6; status = pj_sockaddr_set_str_addr(af, addr, cp); if (status != PJ_SUCCESS) return status; addr->ipv6.sin6_port = pj_htons(port); return PJ_SUCCESS; }
void natclient_connect_with_user(struct ice_trans_s* icetrans, const char *usr_id) { char linebuf[80]; unsigned media_cnt = 0; unsigned comp0_port = 0; char comp0_addr[80]; pj_bool_t done = PJ_FALSE; reset_rem_info(icetrans); comp0_addr[0] = '\0'; int af, cnt; char foundation[32], transport[12], ipaddr[80], type[32]; pj_str_t tmpaddr; int comp_id, prio, port; pj_ice_sess_cand *cand; pj_status_t status; char full_url[1024]; char buff[5*1024]; strcpy(full_url, gUrl); // plus URL sprintf(&full_url[strlen(full_url)], "/peer/getPeer/%s", usr_id); // plus API PJ_LOG(4, ("[Debug] URL: %s \n", full_url)); http_get_request(full_url, &buff[0]); char *value; xmlNode *cur_node = NULL; xmlNode *a_node = xml_get_node_by_name(buff, "registerPeer"); assert(a_node != NULL); //printf("DEBUG %s, %d \n", __FILE__, __LINE__); value = (char *)xml_xmlnode_get_content_by_name(a_node->children, "ufrag"); strcpy(icetrans->rem.ufrag, value); free(value); value = (char *)xml_xmlnode_get_content_by_name(a_node->children, "pwd"); strcpy(icetrans->rem.pwd, value); free(value); a_node = xml_get_node_by_name(buff, "candidateList"); //printf("DEBUG %s, %d \n", __FILE__, __LINE__); for (cur_node = a_node->children; cur_node; cur_node = cur_node->next) { // printf("[DEBUG] %s \n", cur_node->name); if (cur_node->type == XML_ELEMENT_NODE) { if (strcmp(cur_node->name, "comp_1") == 0) { value = (char *)xml_xmlnode_get_content_by_name(cur_node, "ip"); strcpy(comp0_addr, value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "port"); comp0_port = atoi(value); free(value); }else { value = (char *)xml_xmlnode_get_content_by_name(cur_node, "foundation"); strcpy(foundation, value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "comp_id"); comp_id = atoi(value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "transport"); strcpy(transport, value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "prio"); prio = atoi(value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "ip"); strcpy(ipaddr, value); //if (cur_node == a_node->children) // strcpy(comp0_addr, value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "port"); port = atoi(value); if (cur_node == a_node->children) comp0_port = atoi(value); free(value); value = (char *)xml_xmlnode_get_content_by_name(cur_node, "type"); strcpy(type, value); free(value); PJ_LOG(4,(__FUNCTION__, "DEBUG %s %d %s %d %s %d typ %s", foundation, comp_id, transport, prio, ipaddr, port, type)); cand = &icetrans->rem.cand[icetrans->rem.cand_cnt]; pj_bzero(cand, sizeof(*cand)); if (strcmp(type, "host")==0) cand->type = PJ_ICE_CAND_TYPE_HOST; else if (strcmp(type, "srflx")==0) cand->type = PJ_ICE_CAND_TYPE_SRFLX; else if (strcmp(type, "relay")==0) cand->type = PJ_ICE_CAND_TYPE_RELAYED; else { PJ_LOG(1, (THIS_FILE, "Error: invalid candidate type '%s'", type)); goto on_error; } cand->comp_id = (pj_uint8_t)comp_id; pj_strdup2(icetrans->pool, &cand->foundation, foundation); cand->prio = prio; if (strchr(ipaddr, ':')) af = pj_AF_INET6(); else af = pj_AF_INET(); tmpaddr = pj_str(ipaddr); pj_sockaddr_init(af, &cand->addr, NULL, 0); status = pj_sockaddr_set_str_addr(af, &cand->addr, &tmpaddr); if (status != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, "Error: invalid IP address '%s'", ipaddr)); goto on_error; } pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)port); ++icetrans->rem.cand_cnt; if (cand->comp_id > icetrans->rem.comp_cnt) icetrans->rem.comp_cnt = cand->comp_id; } } } if (icetrans->rem.cand_cnt==0 || icetrans->rem.ufrag[0]==0 || icetrans->rem.pwd[0]==0 || icetrans->rem.comp_cnt == 0) { PJ_LOG(1, (THIS_FILE, "Error: not enough info")); goto on_error; } if (comp0_port==0 || comp0_addr[0]=='\0') { PJ_LOG(1, (THIS_FILE, "Error: default address for component 0 not found")); goto on_error; } else { int af; pj_str_t tmp_addr; pj_status_t status; if (strchr(comp0_addr, ':')) af = pj_AF_INET6(); else af = pj_AF_INET(); pj_sockaddr_init(af, &icetrans->rem.def_addr[0], NULL, 0); tmp_addr = pj_str(comp0_addr); status = pj_sockaddr_set_str_addr(af, &icetrans->rem.def_addr[0], &tmp_addr); if (status != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, "Invalid IP address in c= line")); goto on_error; } pj_sockaddr_set_port(&icetrans->rem.def_addr[0], (pj_uint16_t)comp0_port); } PJ_LOG(3, (THIS_FILE, "Done, %d remote candidate(s) added", icetrans->rem.cand_cnt)); return; on_error: reset_rem_info(icetrans); }
/* * Input and parse SDP from the remote (containing remote's ICE information) * and save it to global variables. */ static void icedemo_input_remote(void) { char linebuf[80]; unsigned media_cnt = 0; unsigned comp0_port = 0; char comp0_addr[80]; pj_bool_t done = PJ_FALSE; puts("Paste SDP from remote host, end with empty line"); reset_rem_info(); comp0_addr[0] = '\0'; while (!done) { int len; char *line; printf(">"); if (stdout) fflush(stdout); if (fgets(linebuf, sizeof(linebuf), stdin)==NULL) break; len = strlen(linebuf); while (len && (linebuf[len-1] == '\r' || linebuf[len-1] == '\n')) linebuf[--len] = '\0'; line = linebuf; while (len && pj_isspace(*line)) ++line, --len; if (len==0) break; /* Ignore subsequent media descriptors */ if (media_cnt > 1) continue; switch (line[0]) { case 'm': { int cnt; char media[32], portstr[32]; ++media_cnt; if (media_cnt > 1) { puts("Media line ignored"); break; } cnt = sscanf(line+2, "%s %s RTP/", media, portstr); if (cnt != 2) { PJ_LOG(1,(THIS_FILE, "Error parsing media line")); goto on_error; } comp0_port = atoi(portstr); } break; case 'c': { int cnt; char c[32], net[32], ip[80]; cnt = sscanf(line+2, "%s %s %s", c, net, ip); if (cnt != 3) { PJ_LOG(1,(THIS_FILE, "Error parsing connection line")); goto on_error; } strcpy(comp0_addr, ip); } break; case 'a': { char *attr = strtok(line+2, ": \t\r\n"); if (strcmp(attr, "ice-ufrag")==0) { strcpy(icedemo.rem.ufrag, attr+strlen(attr)+1); } else if (strcmp(attr, "ice-pwd")==0) { strcpy(icedemo.rem.pwd, attr+strlen(attr)+1); } else if (strcmp(attr, "rtcp")==0) { char *val = attr+strlen(attr)+1; int af, cnt; int port; char net[32], ip[64]; pj_str_t tmp_addr; pj_status_t status; cnt = sscanf(val, "%d IN %s %s", &port, net, ip); if (cnt != 3) { PJ_LOG(1,(THIS_FILE, "Error parsing rtcp attribute")); goto on_error; } if (strchr(ip, ':')) af = pj_AF_INET6(); else af = pj_AF_INET(); pj_sockaddr_init(af, &icedemo.rem.def_addr[1], NULL, 0); tmp_addr = pj_str(ip); status = pj_sockaddr_set_str_addr(af, &icedemo.rem.def_addr[1], &tmp_addr); if (status != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, "Invalid IP address")); goto on_error; } pj_sockaddr_set_port(&icedemo.rem.def_addr[1], (pj_uint16_t)port); } else if (strcmp(attr, "candidate")==0) { char *sdpcand = attr+strlen(attr)+1; int af, cnt; char foundation[32], transport[12], ipaddr[80], type[32]; pj_str_t tmpaddr; int comp_id, prio, port; pj_ice_sess_cand *cand; pj_status_t status; cnt = sscanf(sdpcand, "%s %d %s %d %s %d typ %s", foundation, &comp_id, transport, &prio, ipaddr, &port, type); if (cnt != 7) { PJ_LOG(1, (THIS_FILE, "error: Invalid ICE candidate line")); goto on_error; } cand = &icedemo.rem.cand[icedemo.rem.cand_cnt]; pj_bzero(cand, sizeof(*cand)); if (strcmp(type, "host")==0) cand->type = PJ_ICE_CAND_TYPE_HOST; else if (strcmp(type, "srflx")==0) cand->type = PJ_ICE_CAND_TYPE_SRFLX; else if (strcmp(type, "relay")==0) cand->type = PJ_ICE_CAND_TYPE_RELAYED; else { PJ_LOG(1, (THIS_FILE, "Error: invalid candidate type '%s'", type)); goto on_error; } cand->comp_id = (pj_uint8_t)comp_id; pj_strdup2(icedemo.pool, &cand->foundation, foundation); cand->prio = prio; if (strchr(ipaddr, ':')) af = pj_AF_INET6(); else af = pj_AF_INET(); tmpaddr = pj_str(ipaddr); pj_sockaddr_init(af, &cand->addr, NULL, 0); status = pj_sockaddr_set_str_addr(af, &cand->addr, &tmpaddr); if (status != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, "Error: invalid IP address '%s'", ipaddr)); goto on_error; } pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)port); ++icedemo.rem.cand_cnt; if (cand->comp_id > icedemo.rem.comp_cnt) icedemo.rem.comp_cnt = cand->comp_id; } } break; } } if (icedemo.rem.cand_cnt==0 || icedemo.rem.ufrag[0]==0 || icedemo.rem.pwd[0]==0 || icedemo.rem.comp_cnt == 0) { PJ_LOG(1, (THIS_FILE, "Error: not enough info")); goto on_error; } if (comp0_port==0 || comp0_addr[0]=='\0') { PJ_LOG(1, (THIS_FILE, "Error: default address for component 0 not found")); goto on_error; } else { int af; pj_str_t tmp_addr; pj_status_t status; if (strchr(comp0_addr, ':')) af = pj_AF_INET6(); else af = pj_AF_INET(); pj_sockaddr_init(af, &icedemo.rem.def_addr[0], NULL, 0); tmp_addr = pj_str(comp0_addr); status = pj_sockaddr_set_str_addr(af, &icedemo.rem.def_addr[0], &tmp_addr); if (status != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, "Invalid IP address in c= line")); goto on_error; } pj_sockaddr_set_port(&icedemo.rem.def_addr[0], (pj_uint16_t)comp0_port); } PJ_LOG(3, (THIS_FILE, "Done, %d remote candidate(s) added", icedemo.rem.cand_cnt)); return; on_error: reset_rem_info(); }