/* The 3pcc-A script sends "invalid" SIP that is parsed by this * sip_parser. We must accept headers without any leading request/ * response line: * * <sendCmd> * <![CDATA[ * Call-ID: [call_id] * [$1] * ]]> * </sendCmd> */ TEST(Parser, get_call_id_github_0101) { // github-#0101 const char *input = "Call-ID: [email protected]\r\n" "Content-Type: application/sdp\r\n" "Content-Length: 129\r\n\r\n" "v=0\r\no=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n" "s=-\r\nc=IN IP4 127.0.0.1\r\nt=0 0\r\n" "m=audio 6000 RTP/AVP 0\r\na=rtpmap:0 PCMU/8000"; EXPECT_STREQ("[email protected]", get_call_id(input)); }
static at_error_t enum_calls (plugin_t *p, call_cb_t cb, void *opaque) { at_error_t err; int canc = at_cancel_disable (); DBusMessage *msg = modem_req_new (p, "VoiceCallManager", "GetCalls"); if (msg == NULL) { err = AT_CME_ENOMEM; goto out; } msg = ofono_query (msg, &err); if (msg == NULL) goto out; DBusMessageIter args; if (!dbus_message_iter_init (msg, &args) || dbus_message_iter_get_arg_type (&args) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type (&args) != DBUS_TYPE_STRUCT) { dbus_message_unref (msg); err = AT_CME_ERROR_0; goto out; } DBusMessageIter calls; for (dbus_message_iter_recurse (&args, &calls); dbus_message_iter_get_arg_type (&calls) != DBUS_TYPE_INVALID; dbus_message_iter_next (&calls)) { const char *callpath; DBusMessageIter call; int id = -1; dbus_message_iter_recurse (&calls, &call); if (dbus_message_iter_get_arg_type (&call) != DBUS_TYPE_OBJECT_PATH) continue; dbus_message_iter_get_basic (&call, &callpath); id = get_call_id (callpath); if (id == -1) continue; dbus_message_iter_next (&call); if (cb (id, &call, opaque)) break; } dbus_message_unref (msg); assert (err == AT_OK); out: at_cancel_enable (canc); return err; }
static int get_source(struct _sipcapture_object *sco, enum hash_source source, str *source_string) { source_string->s = NULL; source_string->len = 0; switch(source) { case hs_call_id: return get_call_id(sco, source_string); case hs_from_user: return get_from_user(sco, source_string); case hs_to_user: return get_to_user(sco, source_string); default: LM_ERR("unknown hash source %i.\n", (int)source); return -1; } }
int do_sip_reply_invite(pvp_uthttp put, char **ut_buf, u32 *pack_len) { const static char FLG_INIP4[] = "IN IP4 "; const static char FLG_VPORT[] = "m=video "; char cli_ip[16] = {0}; // outer server ip char *pstr = NULL; char sport[8] = {0}; /*Source port*/ char r_src[64] = {0}; char r_dst[64] = {0}; char lip[16] = {0}; char dip[16] = {0}; char *ptr = NULL; u16 nlport = 0; char call_id[128] = {0}; puts("******** 1"); if ((pstr = strstr(*ut_buf, FLG_VPORT)) != NULL) { puts("******** 2"); puts(*ut_buf); pstr += sizeof(FLG_VPORT)-1; sscanf(pstr, "%[0-9]", sport); if ((nlport = pplist_getidle_port_x()) == 0) { logwar_out("get idle port failed!"); return -1; } puts("******** 3"); // replace ip if ((ptr = strnstr(*ut_buf, FLG_INIP4, *pack_len, true)) != NULL) { ptr += sizeof(FLG_INIP4)-1; sscanf(ptr, "%[0-9.]", dip); inet_ultoa(__gg.outer_addr, lip); sprintf(r_src, "%s%s", FLG_INIP4, dip); //sprintf(r_dst, "%s%s", FLG_INIP4, g_value[L_AUTHIP]); sprintf(r_dst, "%s%s", FLG_INIP4, lip); strreplace_pos(NULL, NULL, ut_buf, r_src, r_dst, -1, pack_len); } puts("******** 4"); // replace port sprintf(r_src, "%s%s", FLG_VPORT, sport); sprintf(r_dst, "%s%d", FLG_VPORT, nlport); strreplace_pos(NULL,NULL, ut_buf, r_src, r_dst, 1, pack_len); inet_ultoa(put->src_ip, cli_ip); // replace invite ip replace_cmd_ip_port(ut_buf, pack_len, cli_ip, put->src_port); puts("******** 5"); // start proxy char camera_id[32] = {0}; int ret = -1; clivlist *pcvn = NULL; if (oss_malloc(&pcvn, sizeof(clivlist)) < 0) return -1; get_virtual_cameraid(camera_id); strcpy(pcvn->visit_user, cli_ip); strcpy(pcvn->camera_id, camera_id); //if (is_tms()) //pcvn->lip = __gg.inner_addr; //else pcvn->lip = __gg.outer_addr; pcvn->dip = inet_atoul(dip); pcvn->lvport = nlport; pcvn->dvport = atoi(sport); pcvn->platform_id = a_get_pmid(); // pcvn->vstream_tout = put->session_tout; // // 信令超时时间需要很长,如果视频流使用相同超时时间,会有大量已经使用完的视频进程逗留在系统中 pcvn->vstream_tout = 60; pcvn->bind_video_port = nlport; puts("******** 6"); if (get_call_id(*ut_buf, *pack_len, call_id, sizeof(call_id)) == NULL) logdbg_out("获取Call id 失败!"); else if ( ! gl_set_data(call_id, (char*)&nlport, sizeof(nlport))) logdbg_out("记录Call id 失败!"); ret = __start_vs_udp_proxy(pcvn, true, __gg.ferry_port + 1); oss_free(&pcvn); //sip_replace_contact(ut_buf, pack_len, g_value[L_AUTHIP], 5060); //do_sip_reply_replace_by_key(put, SIP_FLAG_CONTACT, ut_buf, pack_len); } return 1; }
/* TODO: redesign to avoid longjmp/setjmp. Several variables here have a volatile qualifier to silence warnings from gcc < 3.0. Remove the volatile qualifiers if longjmp/setjmp are removed. */ int main(int argc, char **argv, char **envp) { struct in_addr inetaddr; volatile int callmgr_sock = -1; char ttydev[PATH_MAX]; int pty_fd, tty_fd, gre_fd, rc; volatile pid_t parent_pid, child_pid; u_int16_t call_id, peer_call_id; char buf[128]; int pppdargc; char **pppdargv; char phonenrbuf[65]; /* maximum length of field plus one for the trailing * '\0' */ char * volatile phonenr = NULL; volatile int launchpppd = 1, debug = 0, nodaemon = 0; while(1){ /* structure with all recognised options for pptp */ static struct option long_options[] = { {"phone", 1, 0, 0}, {"nolaunchpppd", 0, 0, 0}, {"quirks", 1, 0, 0}, {"debug", 0, 0, 0}, {"sync", 0, 0, 0}, {"timeout", 1, 0, 0}, {"logstring", 1, 0, 0}, {"localbind", 1, 0, 0}, {"loglevel", 1, 0, 0}, {"nobuffer", 0, 0, 0}, {"idle-wait", 1, 0, 0}, {"max-echo-wait", 1, 0, 0}, {"version", 0, 0, 0}, {"nodaemon", 0, 0, 0}, {0, 0, 0, 0} }; int option_index = 0; int c; c = getopt_long (argc, argv, "", long_options, &option_index); if (c == -1) break; /* no more options */ switch (c) { case 0: if (option_index == 0) { /* --phone specified */ /* copy it to a buffer, as the argv's will be overwritten * by inststr() */ strncpy(phonenrbuf,optarg,sizeof(phonenrbuf)); phonenrbuf[sizeof(phonenrbuf) - 1] = '\0'; phonenr = phonenrbuf; } else if (option_index == 1) {/* --nolaunchpppd specified */ launchpppd = 0; } else if (option_index == 2) {/* --quirks specified */ if (set_quirk_index(find_quirk(optarg))) usage(argv[0]); } else if (option_index == 3) {/* --debug */ debug = 1; } else if (option_index == 4) {/* --sync specified */ syncppp = 1; } else if (option_index == 5) {/* --timeout */ float new_packet_timeout = atof(optarg); if (new_packet_timeout < 0.0099 || new_packet_timeout > 10) { fprintf(stderr, "Packet timeout %s (%f) out of range: " "should be between 0.01 and 10 seconds\n", optarg, new_packet_timeout); log("Packet timeout %s (%f) out of range: should be" "between 0.01 and 10 seconds", optarg, new_packet_timeout); exit(2); } else { packet_timeout_usecs = new_packet_timeout * 1000000; } } else if (option_index == 6) {/* --logstring */ log_string = strdup(optarg); } else if (option_index == 7) {/* --localbind */ if (inet_pton(AF_INET, optarg, (void *) &localbind) < 1) { fprintf(stderr, "Local bind address %s invalid\n", optarg); log("Local bind address %s invalid\n", optarg); exit(2); } } else if (option_index == 8) { /* --loglevel */ log_level = atoi(optarg); if (log_level < 0 || log_level > 2) usage(argv[0]); } else if (option_index == 9) { /* --nobuffer */ disable_buffer = 1; } else if (option_index == 10) { /* --idle-wait */ int x = atoi(optarg); if (x < 0) { fprintf(stderr, "--idle-wait must not be negative\n"); log("--idle-wait must not be negative\n"); exit(2); } else { idle_wait = x; } } else if (option_index == 11) { /* --max-echo-wait */ int x = atoi(optarg); if (x < 0) { fprintf(stderr, "--max-echo-wait must not be negative\n"); log("--max-echo-wait must not be negative\n"); exit(2); } else { max_echo_wait = x; } fprintf(stderr, "--max-echo-wait ignored, not yet implemented\n"); } else if (option_index == 12) { /* --version */ fprintf(stdout, "%s\n", version); exit(0); } else if (option_index == 13) {/* --nodaemon */ nodaemon = 1; } break; case '?': /* unrecognised option */ /* fall through */ default: usage(argv[0]); } if (c == -1) break; /* no more options for pptp */ } /* at least one argument is required */ if (argc <= optind) usage(argv[0]); /* Get IP address for the hostname in argv[1] */ inetaddr = get_ip_address(argv[optind]); optind++; /* Find the ppp options, extract phone number */ pppdargc = argc - optind; pppdargv = argv + optind; log("The synchronous pptp option is %sactivated\n", syncppp ? "" : "NOT "); /* Now we have the peer address, bind the GRE socket early, before starting pppd. This prevents the ICMP Unreachable bug documented in <1026868263.2855.67.camel@jander> */ gre_fd = pptp_gre_bind(inetaddr); if (gre_fd < 0) { close(callmgr_sock); fatal("Cannot bind GRE socket, aborting."); } /* Find an open pty/tty pair. */ if(launchpppd){ rc = openpty (&pty_fd, &tty_fd, ttydev, NULL, NULL); if (rc < 0) { close(callmgr_sock); fatal("Could not find free pty."); } #if defined(__linux__) /* * if we do not turn off echo now, then if pppd sleeps for any * length of time (DNS timeouts or whatever) the other end of the * connect may detect the link as looped. Other OSen may want this * as well, but for now linux gets it. */ { struct termios tios; tcgetattr(tty_fd, &tios); cfmakeraw(&tios); tcsetattr(tty_fd, TCSAFLUSH, &tios); } #endif /* fork and wait. */ signal(SIGUSR1, do_nothing); /* don't die */ signal(SIGCHLD, do_nothing); /* don't ignore SIGCHLD */ parent_pid = getpid(); switch (child_pid = fork()) { case -1: fatal("Could not fork pppd process"); case 0: /* I'm the child! */ close (tty_fd); signal(SIGUSR1, SIG_DFL); child_pid = getpid(); break; default: /* parent */ close (pty_fd); close (gre_fd); /* * There is still a very small race condition here. If a signal * occurs after signaled is checked but before pause is called, * things will hang. */ if (!signaled) { pause(); /* wait for the signal */ } if (signaled == SIGCHLD) fatal("Child process died"); launch_pppd(ttydev, pppdargc, pppdargv); /* launch pppd */ perror("Error"); fatal("Could not launch pppd"); } } else { /* ! launchpppd */ pty_fd = tty_fd = STDIN_FILENO; /* close unused file descriptor, that is redirected to the pty */ close(STDOUT_FILENO); child_pid = getpid(); parent_pid = 0; /* don't kill pppd */ } do { /* * Open connection to call manager (Launch call manager if necessary.) */ callmgr_sock = open_callmgr(inetaddr, phonenr, argc, argv, envp, pty_fd, gre_fd); /* Exchange PIDs, get call ID */ } while (get_call_id(callmgr_sock, parent_pid, child_pid, &call_id, &peer_call_id) < 0); /* Send signal to wake up pppd task */ if (launchpppd) { kill(parent_pid, SIGUSR1); sleep(2); /* become a daemon */ if (!(debug || nodaemon) && daemon(0, 0) != 0) { perror("daemon"); } } else { /* re-open stderr as /dev/null to release it */ file2fd("/dev/null", "wb", STDERR_FILENO); } snprintf(buf, sizeof(buf), "pptp: GRE-to-PPP gateway on %s", ttyname(tty_fd)); #ifdef PR_SET_NAME rc = prctl(PR_SET_NAME, "pptpgw", 0, 0, 0); if (rc != 0) perror("prctl"); #endif inststr(argc, argv, envp, buf); if (sigsetjmp(env, 1)!= 0) goto shutdown; signal(SIGINT, sighandler); signal(SIGTERM, sighandler); signal(SIGKILL, sighandler); signal(SIGCHLD, sighandler); signal(SIGUSR1, sigstats); /* Do GRE copy until close. */ pptp_gre_copy(call_id, peer_call_id, pty_fd, gre_fd); shutdown: /* on close, kill all. */ if(launchpppd) kill(parent_pid, SIGTERM); close(pty_fd); close(callmgr_sock); exit(0); }
static int pptp_start_client(void) { socklen_t len; struct sockaddr_pppox src_addr,dst_addr; struct hostent *hostinfo; #if !defined(__UCLIBC__) \ || (__UCLIBC_MAJOR__ == 0 \ && (__UCLIBC_MINOR__ < 9 || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 31))) /* force ns refresh from resolv.conf with uClibc pre-0.9.31 */ res_init(); #endif hostinfo=gethostbyname(pptp_server); if (!hostinfo) { error("PPTP: Unknown host %s\n", pptp_server); return -1; } dst_addr.sa_addr.pptp.sin_addr=*(struct in_addr*)hostinfo->h_addr; route_del(&rt); if (route2man) route_add(dst_addr.sa_addr.pptp.sin_addr, &rt); { int sock; struct sockaddr_in addr; len=sizeof(addr); addr.sin_addr=dst_addr.sa_addr.pptp.sin_addr; addr.sin_family=AF_INET; addr.sin_port=htons(1700); sock=socket(AF_INET,SOCK_DGRAM,0); if (connect(sock,(struct sockaddr*)&addr,sizeof(addr))) { close(sock); error("PPTP: connect failed (%s)\n",strerror(errno)); route_del(&rt); return -1; } getsockname(sock,(struct sockaddr*)&addr,&len); src_addr.sa_addr.pptp.sin_addr=addr.sin_addr; close(sock); } //info("PPTP: connect server=%s\n",inet_ntoa(conn.sin_addr)); //conn.loc_addr.s_addr=INADDR_NONE; //conn.timeout=1; //conn.window=pptp_window; src_addr.sa_family=AF_PPPOX; src_addr.sa_protocol=PX_PROTO_PPTP; src_addr.sa_addr.pptp.call_id=0; dst_addr.sa_family=AF_PPPOX; dst_addr.sa_protocol=PX_PROTO_PPTP; dst_addr.sa_addr.pptp.call_id=0; pptp_fd=socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_PPTP); if (pptp_fd<0) { error("PPTP: failed to create PPTP socket (%s)\n",strerror(errno)); route_del(&rt); return -1; } if (bind(pptp_fd,(struct sockaddr*)&src_addr,sizeof(src_addr))) { close(pptp_fd); error("PPTP: failed to bind PPTP socket (%s)\n",strerror(errno)); route_del(&rt); return -1; } len=sizeof(src_addr); getsockname(pptp_fd,(struct sockaddr*)&src_addr,&len); call_ID=src_addr.sa_addr.pptp.call_id; /* * Open connection to call manager (Launch call manager if necessary.) */ callmgr_sock = -1; do { if (callmgr_sock >= 0) close(callmgr_sock); callmgr_sock = open_callmgr(src_addr.sa_addr.pptp.call_id, dst_addr.sa_addr.pptp.sin_addr, pptp_phone, 50); if (callmgr_sock < 0) { close(pptp_fd); route_del(&rt); return -1; } /* Exchange PIDs, get call ID */ } while (get_call_id(callmgr_sock, getpid(), getpid(), &dst_addr.sa_addr.pptp.call_id) < 0); if (connect(pptp_fd,(struct sockaddr*)&dst_addr,sizeof(dst_addr))) { close(callmgr_sock); close(pptp_fd); error("PPTP: failed to connect PPTP socket (%s)\n",strerror(errno)); route_del(&rt); return -1; } sprintf(ppp_devnam,"pptp (%s)", inet_ntoa(dst_addr.sa_addr.pptp.sin_addr)); return pptp_fd; }
static int pptp_start_client(void) { socklen_t len; struct sockaddr_pppox src_addr,dst_addr; struct hostent *hostinfo; hostinfo=gethostbyname(pptp_server); if (!hostinfo) { error("PPTP: Unknown host %s\n", pptp_server); return -1; } dst_addr.sa_addr.pptp.sin_addr=*(struct in_addr*)hostinfo->h_addr; { int sock; struct sockaddr_in addr; len=sizeof(addr); addr.sin_addr=dst_addr.sa_addr.pptp.sin_addr; addr.sin_family=AF_INET; addr.sin_port=htons(1700); sock=socket(AF_INET,SOCK_DGRAM,0); if (connect(sock,(struct sockaddr*)&addr,sizeof(addr))) { close(sock); error("PPTP: connect failed (%s)\n",strerror(errno)); return -1; } getsockname(sock,(struct sockaddr*)&addr,&len); src_addr.sa_addr.pptp.sin_addr=addr.sin_addr; close(sock); } src_addr.sa_family=AF_PPPOX; src_addr.sa_protocol=PX_PROTO_PPTP; src_addr.sa_addr.pptp.call_id=0; dst_addr.sa_family=AF_PPPOX; dst_addr.sa_protocol=PX_PROTO_PPTP; dst_addr.sa_addr.pptp.call_id=0; pptp_fd=socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_PPTP); if (pptp_fd<0) { error("PPTP: failed to create PPTP socket (%s)\n",strerror(errno)); return -1; } if (bind(pptp_fd,(struct sockaddr*)&src_addr,sizeof(src_addr))) { close(pptp_fd); error("PPTP: failed to bind PPTP socket (%s)\n",strerror(errno)); return -1; } len=sizeof(src_addr); getsockname(pptp_fd,(struct sockaddr*)&src_addr,&len); call_ID=src_addr.sa_addr.pptp.call_id; do { /* * Open connection to call manager (Launch call manager if necessary.) */ callmgr_sock = open_callmgr(src_addr.sa_addr.pptp.call_id,dst_addr.sa_addr.pptp.sin_addr, pptp_phone, pptp_window); if (callmgr_sock<0) { close(pptp_fd); return -1; } /* Exchange PIDs, get call ID */ } while (get_call_id(callmgr_sock, getpid(), getpid(), &dst_addr.sa_addr.pptp.call_id) < 0); if (connect(pptp_fd,(struct sockaddr*)&dst_addr,sizeof(dst_addr))) { close(callmgr_sock); close(pptp_fd); error("PPTP: failed to connect PPTP socket (%s)\n",strerror(errno)); return -1; } sprintf(ppp_devnam,"pptp (%s)",pptp_server); return pptp_fd; }
int main(int argc, char **argv, char **envp) { struct in_addr inetaddr; int callmgr_sock = -1; char ptydev[PTYMAX], ttydev[TTYMAX]; int pty_fd = -1; int gre_fd = -1; static volatile pid_t child_pid; u_int16_t call_id, peer_call_id; #ifdef EMBED openlog(argv[0],LOG_PID,LOG_USER); #endif if (argc < 2) usage(argv[0]); /* Step 1: Get IP address for the hostname in argv[1] */ for (;;) { inetaddr = get_ip_address(argv[1]); if(inetaddr.s_addr != 0) break; sleep(RESPAWN_DELAY); } /* * open the GRE socket early so that we do not get * ENOPROTOOPT errors if the other end responds too * quickly to our initial connection */ gre_fd = socket(AF_INET, SOCK_RAW, PPTP_PROTO); if (gre_fd < 0) { pptp_error("socket: %s\n", strerror(errno)); sleep(RESPAWN_DELAY); exit(1); } for (;;) { /* Step 2: Open connection to call manager * (Launch call manager if necessary.) */ callmgr_sock = open_callmgr(inetaddr, argc,argv,envp); if(callmgr_sock < 0){ close(gre_fd); pptp_error("Could not open connection to call manager - terminating"); sleep(RESPAWN_DELAY); exit(1); } pptp_debug("callmgr opened - fd = %x", callmgr_sock); /* Step 5: Exchange PIDs, get call ID */ if (get_call_id(callmgr_sock, getpid(), &call_id, &peer_call_id) >= 0) break; close(callmgr_sock); } /* Step 3: Find an open pty/tty pair. */ pty_fd = getpseudotty(ttydev, ptydev); if (pty_fd < 0) { close(gre_fd); close(callmgr_sock); pptp_error("Could not find free pty."); sleep(RESPAWN_DELAY); exit(1); } pptp_debug("got a free ttydev"); /* Step 4: fork and wait. */ signal(SIGUSR1, do_nothing); /* don't die */ switch (child_pid = vfork()) { case -1: signal(SIGUSR1, SIG_DFL); pptp_debug("vfork failed %s", strerror(errno)); sleep(RESPAWN_DELAY); goto shutdown; case 0: /* I'm the child! */ // signal(SIGUSR1, SIG_DFL); pptp_debug("entered child"); pptp_debug("callids established.."); close(callmgr_sock); close(gre_fd); close(pty_fd); launch_pppd(ttydev, argc-2, argv+2); /* launch pppd */ sleep(RESPAWN_DELAY); exit(1); /* in case launch_pppd returns */ break; default: /* parent */ /* * There is still a very small race condition here. If a signal * occurs after signaled is checked but before pause is called, * things will hang. */ #if 0 if (!signaled) { pause(); /* wait for the signal */ } pptp_error("Error %s", strerror(errno)); #endif /*0*/ break; } #if 0 /* Step 5b: Send signal to wake up pppd task */ kill(parent_pid, SIGUSR1); sleep(2); #endif /*0*/ if (sigsetjmp(env, 1)!=0) goto shutdown; signal(SIGINT, sighandler); signal(SIGTERM, sighandler); signal(SIGKILL, sighandler); { char buf[128]; snprintf(buf, sizeof(buf), "pptp: GRE-to-PPP gateway on %s", ptydev); inststr(argc,argv,envp, buf); } /* Step 6: Do GRE copy until close. */ pptp_gre_copy(peer_call_id, call_id, pty_fd, gre_fd, inetaddr); shutdown: /* Make sure pppd exits as well */ if (child_pid > 0) kill(child_pid, SIGTERM); if (gre_fd != -1) close(gre_fd); if (pty_fd != -1) close(pty_fd); if (callmgr_sock != -1) close(callmgr_sock); exit(0); }
TEST(Parser, get_call_id_short_2) { /* The WS surrounding the colon belongs with HCOLON, but the * trailing WS does not. */ EXPECT_STREQ("testshort2 \t ", get_call_id("...\r\nI:\r\n \r\n \t testshort2 \t \r\n\r\n")); }
TEST(Parser, get_call_id_short_1) { EXPECT_STREQ("testshort1", get_call_id("...\r\ni: testshort1\r\n\r\n")); }
TEST(Parser, get_call_id_3) { EXPECT_STREQ("test3", get_call_id("...\r\ncall-id:\r\n\t test3\r\n\r\n")); }
TEST(Parser, get_call_id_2) { EXPECT_STREQ("test2", get_call_id("...\r\nCALL-ID:\r\n test2\r\n\r\n")); }
TEST(Parser, get_call_id_1) { EXPECT_STREQ("test1", get_call_id("...\r\nCall-ID: test1\r\n\r\n")); }