📄 main.c
字号:
char addrs[4][256]; /* RTCP twin session */ if (spa->rtcp == NULL) { spb = spa->rtp; buf[len++] = '\t'; } else { spb = spa->rtcp; buf[len++] = '\t'; buf[len++] = 'C'; buf[len++] = ' '; } addr2char_r(spb->laddr[1], addrs[0], sizeof(addrs[0])); if (spb->addr[1] == NULL) { strcpy(addrs[1], "NONE"); } else { sprintf(addrs[1], "%s:%d", addr2char(spb->addr[1]), addr2port(spb->addr[1])); } addr2char_r(spb->laddr[0], addrs[2], sizeof(addrs[2])); if (spb->addr[0] == NULL) { strcpy(addrs[3], "NONE"); } else { sprintf(addrs[3], "%s:%d", addr2char(spb->addr[0]), addr2port(spb->addr[0])); } len += sprintf(buf + len, "%s/%s: caller = %s:%d/%s, callee = %s:%d/%s, " "stats = %lu/%lu/%lu/%lu, ttl = %d\n", spb->call_id, spb->tag, addrs[0], spb->ports[1], addrs[1], addrs[2], spb->ports[0], addrs[3], spa->pcount[0], spa->pcount[1], spa->pcount[2], spa->pcount[3], spb->ttl); if (len + 512 > sizeof(buf)) { doreply(); len = 0; } } if (len > 0) doreply(); return; break; default: rtpp_log_write(RTPP_LOG_ERR, glog, "unknown command"); ecode = 3; goto goterror; } call_id = argv[1]; if (request != 0 || response != 0 || play != 0) { if (argc < 5 || argc > 6) { rtpp_log_write(RTPP_LOG_ERR, glog, "command syntax error"); ecode = 4; goto goterror; } from_tag = argv[4]; to_tag = argv[5]; if (play != 0 && argv[0][1] != '\0') play = atoi(argv[0] + 1); } if (delete != 0 || record != 0 || noplay != 0) { if (argc < 3 || argc > 4) { rtpp_log_write(RTPP_LOG_ERR, glog, "command syntax error"); ecode = 1; goto goterror; } from_tag = argv[2]; to_tag = argv[3]; } if (request != 0 || response != 0 || delete != 0) { addr = argv[2]; port = argv[3]; /* Process additional options */ external = 1; /* In bridge mode all clients are assumed to be asymmetric */ asymmetric = (bmode != 0) ? 1 : 0; pf = AF_INET; weak = 0; for (cp = argv[0] + 1; *cp != '\0'; cp++) { switch (*cp) { case 'a': case 'A': asymmetric = 1; break; case 'e': case 'E': if (lidx < 0) { rtpp_log_write(RTPP_LOG_ERR, glog, "command syntax error"); ecode = 1; goto goterror; } lia[lidx] = bindaddr[1]; lidx--; break; case 'i': case 'I': if (lidx < 0) { rtpp_log_write(RTPP_LOG_ERR, glog, "command syntax error"); ecode = 1; goto goterror; } lia[lidx] = bindaddr[0]; lidx--; break; case '6': pf = AF_INET6; break; case 's': case 'S': asymmetric = 0; break; case 'w': case 'W': weak = 1; break; default: rtpp_log_write(RTPP_LOG_ERR, glog, "unknown command modifier `%c'", *cp); break; } } if (delete == 0 && addr != NULL && port != NULL && strlen(addr) >= 7) { struct sockaddr_storage tia; if ((n = resolve(sstosa(&tia), pf, addr, port, AI_NUMERICHOST)) == 0) { if (!ishostnull(sstosa(&tia))) { for (i = 0; i < 2; i++) { ia[i] = malloc(SS_LEN(&tia)); if (ia[i] == NULL) { ecode = 5; goto nomem; } memcpy(ia[i], &tia, SS_LEN(&tia)); } /* Set port for RTCP, will work both for IPv4 and IPv6 */ n = ntohs(satosin(ia[1])->sin_port); satosin(ia[1])->sin_port = htons(n + 1); } } else { rtpp_log_write(RTPP_LOG_ERR, glog, "getaddrinfo: %s", gai_strerror(n)); } } } lport = 0; pidx = 1; ndeleted = 0; for (spa = LIST_FIRST(&session_set); spa != NULL; spa = skipnext ? spa : LIST_NEXT(spa, link)) { skipnext = 0; if (spa->rtcp == NULL || spa->call_id == NULL || strcmp(spa->call_id, call_id) != 0) continue; medianum = 0; if ((cmpr1 = compare_session_tags(spa->tag, from_tag, &medianum)) != 0) { i = (request == 0) ? 1 : 0; cmpr = cmpr1; } else if (to_tag != NULL && (cmpr1 = compare_session_tags(spa->tag, to_tag, &medianum)) != 0) { i = (request == 0) ? 0 : 1; cmpr = cmpr1; } else continue; if (delete != 0) { if (weak) spa->weak[i] = 0; else spa->strong = 0; /* This seems to be stable from reiterations, the only side * effect is less efficient work. */ if (spa->strong || spa->weak[0] || spa->weak[1]) { rtpp_log_write(RTPP_LOG_INFO, spa->log, "delete: medianum=%u: removing %s flag, seeing flags to" " continue session (strong=%d, weak=%d/%d)", medianum, weak ? ( i ? "weak[1]" : "weak[0]" ) : "strong", spa->strong, spa->weak[0], spa->weak[1]); /* Skipping to next possible stream for this call */ ++ndeleted; continue; } rtpp_log_write(RTPP_LOG_INFO, spa->log, "forcefully deleting session %d on ports %d/%d", medianum, spa->ports[0], spa->ports[1]); spnext = spa; remove_session(spa, &spnext); if (cmpr == 2) { ++ndeleted; skipnext = 1; spa = spnext; continue; } rebuild_tables(); goto do_ok; } if (play != 0 || noplay != 0) { if (spa->rtps[i] != NULL) { rtp_server_free(spa->rtps[i]); spa->rtps[i] = NULL; rtpp_log_write(RTPP_LOG_INFO, spa->log, "stopping player at port %d", spa->ports[i]); } if (play == 0) { rebuild_tables(); goto do_ok; } } if (play != 0) { while (*codecs != '\0') { n = strtol(codecs, &cp, 10); if (cp == codecs) break; codecs = cp; if (*codecs != '\0') codecs++; spa->rtps[i] = rtp_server_new(pname, n, play); if (spa->rtps[i] == NULL) continue; rtpp_log_write(RTPP_LOG_INFO, spa->log, "%d times playing prompt %s codec %d", play, pname, n); rebuild_tables(); goto do_ok; } rtpp_log_write(RTPP_LOG_ERR, spa->log, "can't create player"); ecode = 6; goto goterror; } if (record != 0) { if (rdir != NULL) { if (spa->rrcs[i] == NULL) { spa->rrcs[i] = ropen(spa, rdir, sdir, i); rtpp_log_write(RTPP_LOG_INFO, spa->log, "starting recording RTP session on port %d", spa->ports[i]); } if (spa->rtcp->rrcs[i] == NULL && rrtcp != 0) { spa->rtcp->rrcs[i] = ropen(spa->rtcp, rdir, sdir, i); rtpp_log_write(RTPP_LOG_INFO, spa->log, "starting recording RTCP session on port %d", spa->rtcp->ports[i]); } } goto do_ok; } if (response == 1 && spa->complete == 0) { j = ishostseq(bindaddr[0], spa->laddr[i]) ? 0 : 1; if (create_listener(spa->laddr[i], PORT_MIN, PORT_MAX, lastport[j], &lport, fds) == -1) { rtpp_log_write(RTPP_LOG_ERR, spa->log, "can't create listener"); ecode = 7; goto goterror; } lastport[j] = lport + 1; spa->fds[i] = fds[0]; spa->rtcp->fds[i] = fds[1]; spa->ports[i] = lport; spa->rtcp->ports[i] = lport + 1; spa->complete = spa->rtcp->complete = 1; rebuild_tables(); } if (weak) spa->weak[i] = 1; else if (response == 0) spa->strong = 1; lport = spa->ports[i]; lia[0] = spa->laddr[i]; pidx = (i == 0) ? 1 : 0; spa->ttl = SESSION_TIMEOUT; if (response == 0) { rtpp_log_write(RTPP_LOG_INFO, spa->log, "adding %s flag to existing session, new=%d/%d/%d", weak ? ( i ? "weak[1]" : "weak[0]" ) : "strong", spa->strong, spa->weak[0], spa->weak[1]); } rtpp_log_write(RTPP_LOG_INFO, spa->log, "lookup on a ports %d/%d, session timer restarted", spa->ports[0], spa->ports[1]); goto writeport; } if (delete != 0 && ndeleted != 0) { /* * Multiple stream deleting stops here because we had to * iterate full list. */ rebuild_tables(); goto do_ok; } rname = NULL; if (delete == 1) rname = "delete"; if (play == 1) rname = "play"; if (noplay == 1) rname = "noplay"; if (record == 1) rname = "record"; if (response == 1) rname = "lookup"; if (rname != NULL) { rtpp_log_write(RTPP_LOG_INFO, glog, "%s request failed: session %s, tags %s/%s not found", rname, call_id, from_tag, to_tag != NULL ? to_tag : "NONE"); if (response == 1) { pidx = -1; goto writeport; } ecode = 8; goto goterror; } rtpp_log_write(RTPP_LOG_INFO, glog, "new session %s, tag %s requested, type %s", call_id, from_tag, weak ? "weak" : "strong"); j = ishostseq(bindaddr[0], lia[0]) ? 0 : 1; if (create_listener(bindaddr[j], PORT_MIN, PORT_MAX, lastport[j], &lport, fds) == -1) { rtpp_log_write(RTPP_LOG_ERR, glog, "can't create listener"); ecode = 10; goto goterror; } lastport[j] = lport + 1; /* Session creation. If creation is requested with weak flag, * set weak[0]. */ spa = malloc(sizeof(*spa)); if (spa == NULL) { ecode = 11; goto nomem; } /* spb is RTCP twin session for this one. */ spb = malloc(sizeof(*spb)); if (spb == NULL) { ecode = 12; goto nomem; } memset(spa, 0, sizeof(*spa)); memset(spb, 0, sizeof(*spb)); for (i = 0; i < 2; i++) spa->fds[i] = spb->fds[i] = -1; spa->call_id = strdup(call_id); if (spa->call_id == NULL) { ecode = 13; goto nomem; } spb->call_id = spa->call_id; spa->tag = strdup(from_tag); if (spa->tag == NULL) { ecode = 14; goto nomem; } spb->tag = spa->tag; for (i = 0; i < 2; i++) { spa->rrcs[i] = NULL; spb->rrcs[i] = NULL; spa->laddr[i] = lia[i]; spb->laddr[i] = lia[i]; } spa->strong = spa->weak[0] = spa->weak[1] = 0; if (weak) spa->weak[0] = 1; else spa->strong = 1; spa->fds[0] = fds[0]; spb->fds[0] = fds[1]; spa->ports[0] = lport; spb->ports[0] = lport + 1; spa->ttl = SESSION_TIMEOUT; spb->ttl = -1; spa->log = rtpp_log_open("rtpproxy", spa->call_id, 0); spb->log = spa->log; spa->rtcp = spb; spb->rtcp = NULL; spa->rtp = NULL; spb->rtp = spa; LIST_INSERT_HEAD(&session_set, spa, link); LIST_INSERT_HEAD(&session_set, spb, link); rebuild_tables(); sessions_created++; rtpp_log_write(RTPP_LOG_INFO, spa->log, "new session on a port %d created, " "tag %s", lport, from_tag);writeport: if (pidx >= 0) { if (ia[0] != NULL && ia[1] != NULL) { /* If address is different from one that recorded update it */ if (!(spa->addr[pidx] != NULL && SA_LEN(ia[0]) == SA_LEN(spa->addr[pidx]) && memcmp(ia[0], spa->addr[pidx], SA_LEN(ia[0])) == 0)) { rtpp_log_write(RTPP_LOG_INFO, spa->log, "pre-filling %s's address " "with %s:%s", (pidx == 0) ? "callee" : "caller", addr, port); if (spa->addr[pidx] != NULL) free(spa->addr[pidx]); spa->addr[pidx] = ia[0]; ia[0] = NULL; } if (!(spa->rtcp->addr[pidx] != NULL && SA_LEN(ia[1]) == SA_LEN(spa->rtcp->addr[pidx]) && memcmp(ia[1], spa->rtcp->addr[pidx], SA_LEN(ia[1])) == 0)) { if (spa->rtcp->addr[pidx] != NULL) free(spa->rtcp->addr[pidx]); spa->rtcp->addr[pidx] = ia[1]; ia[1] = NULL; } } spa->asymmetric[pidx] = spa->rtcp->asymmetric[pidx] = asymmetric; spa->canupdate[pidx] = spa->rtcp->canupdate[pidx] = NOT(asymmetric); } for (i = 0; i < 2; i++) if (ia[i] != NULL) free(ia[i]); cp = buf; len = 0; if (cookie != NULL) { len = sprintf(cp, "%s ", cookie); cp += len; } if (lia[0] == NULL || ishostnull(lia[0])) len += sprintf(cp, "%d\n", lport); else len += sprintf(cp, "%d %s%s\n", lport, addr2char(lia[0]), (lia[0]->sa_family == AF_INET) ? "" : " 6");doreply: doreply(); return;nomem: rtpp_log_write(RTPP_LOG_ERR, glog, "can't allocate memory"); for (i = 0; i < 2; i++) if (ia[i] != NULL) free(ia[i]); if (spa != NULL) { if (spa->call_id != NULL) free(spa->call_id); free(spa); } if (spb != NULL) free(spb); for (i = 0; i < 2; i++) if (fds[i] != -1) close(fds[i]);goterror: if (cookie != NULL) len = sprintf(buf, "%s E%d\n", cookie, ecode); else len = sprintf(buf, "E%d\n", ecode); goto doreply;do_ok: if (cookie != NULL) len = sprintf(buf, "%s\n", cookie); else { strcpy(buf, "0\n"); len = 2; } goto doreply;}static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -