⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mediaproxy.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    uri = get_from(msg)->uri;    if (uri.len == 0)        return notfound;    if (strncmp(uri.s, "sip:", 4)==0) {        uri.s += 4;        uri.len -= 4;    }    if ((ptr = strfind(uri.s, uri.len, ";", 1))!=NULL) {        uri.len = ptr - uri.s;    }    return uri;}/* Get To tag */static strgetToAddress(struct sip_msg *msg){    static char buf[16] = "unknown"; // buf is here for a reason. don't    static str notfound = {buf, 7};  // use the constant string directly!    str uri;    char *ptr;    if (!msg->to) {        LOG(L_ERR, "error: mediaproxy/getToAddress(): missing To: field\n");        return notfound;    }    uri = get_to(msg)->uri;    if (uri.len == 0)        return notfound;    if (strncmp(uri.s, "sip:", 4)==0) {        uri.s += 4;        uri.len -= 4;    }    if ((ptr = strfind(uri.s, uri.len, ";", 1))!=NULL) {        uri.len = ptr - uri.s;    }    return uri;}/* Get From tag */static strgetFromTag(struct sip_msg *msg){    static char buf[4] = "";        // buf is here for a reason. don't    static str notfound = {buf, 0}; // use the constant string directly!    str tag;    if (parse_from_header(msg) == -1) {        LOG(L_ERR, "error: mediaproxy/getFromTag(): error parsing From: field\n");        return notfound;    }    tag = get_from(msg)->tag_value;    if (tag.len == 0)        return notfound;    return tag;}/* Get To tag */static strgetToTag(struct sip_msg *msg){    static char buf[4] = "";        // buf is here for a reason. don't    static str notfound = {buf, 0}; // use the constant string directly!    str tag;    if (!msg->to) {        LOG(L_ERR, "error: mediaproxy/getToTag(): missing To: field\n");        return notfound;    }    tag = get_to(msg)->tag_value;    if (tag.len == 0)        return notfound;    return tag;}/* Extract User-Agent */static strgetUserAgent(struct sip_msg* msg){    static char buf[16] = "unknown-agent"; // buf is here for a reason. don't    static str notfound = {buf, 13};       // use the constant string directly!    str block, server;    char *ptr;    if ((parse_headers(msg, HDR_USERAGENT, 0)!=-1) && msg->user_agent &&        msg->user_agent->body.len>0) {        return msg->user_agent->body;    }    // If we can't find user-agent, look after the Server: field    // This is a temporary hack. Normally it should be extracted by ser    // (either as the Server field, or if User-Agent is missing in place    // of the User-Agent field)    block.s   = msg->buf;    block.len = msg->len;    ptr = findLineStartingWith(&block, "Server:", True);    if (!ptr)        return notfound;    server.s   = ptr + 7;    server.len = findendline(server.s, block.s+block.len-server.s) - server.s;    trim(&server);    if (server.len == 0)        return notfound;    return server;}// Get URI from the Contact: field.static BoolgetContactURI(struct sip_msg* msg, struct sip_uri *uri, contact_t** _c){    if ((parse_headers(msg, HDR_CONTACT, 0) == -1) || !msg->contact)        return False;    if (!msg->contact->parsed && parse_contact(msg->contact) < 0) {        LOG(L_ERR, "error: mediaproxy/getContactURI(): cannot parse Contact header\n");        return False;    }    *_c = ((contact_body_t*)msg->contact->parsed)->contacts;    if (*_c == NULL) {        return False;    }    if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {        LOG(L_ERR, "error: mediaproxy/getContactURI(): cannot parse Contact URI\n");        return False;    }    return True;}// Functions to manipulate the SDP message bodystatic BoolcheckContentType(struct sip_msg *msg){    str type;    if (!msg->content_type) {        LOG(L_WARN, "warning: mediaproxy/checkContentType(): Content-Type "            "header missing! Let's assume the content is text/plain ;-)\n");        return True;    }    type = msg->content_type->body;    trim(&type);    if (strncasecmp(type.s, "application/sdp", 15) != 0) {        LOG(L_ERR, "error: mediaproxy/checkContentType(): invalid Content-Type "            "for SDP message\n");        return False;    }    if (!(isspace((int)type.s[15]) || type.s[15] == ';' || type.s[15] == 0)) {        LOG(L_ERR,"error: mediaproxy/checkContentType(): invalid character "            "after Content-Type!\n");        return False;    }    return True;}// Get the SDP message from SIP message and check it's Content-Type// return -1 on error, 0 if empty message, 1 if message present and not emptystatic intgetSDPMessage(struct sip_msg *msg, str *sdp){    sdp->s = get_body(msg);    if (sdp->s==NULL) {        LOG(L_ERR, "error: mediaproxy/getSDPMessage(): cannot get the SDP body from SIP message\n");        return -1;    }    sdp->len = msg->buf + msg->len - sdp->s;    if (sdp->len==0) {        // 0 length body is ok for ACK messages        if (!(msg->first_line.type == SIP_REQUEST &&              msg->first_line.u.request.method_value == METHOD_ACK)) {            LOG(L_ERR, "error: mediaproxy/getSDPMessage(): SDP message has zero length\n");        }        return 0;    }    if (!checkContentType(msg)) {        LOG(L_ERR, "error: mediaproxy/getSDPMessage(): content type is not `application/sdp'\n");        return -1;    }    return 1;}// will return the ip address present in a `c=' line in the given block// returns: -1 on error, 0 if not found, 1 if foundstatic intgetMediaIPFromBlock(str *block, str *mediaip){    str tokens[3], zone;    char *ptr;    int count;    ptr = findLineStartingWith(block, "c=", False);    if (!ptr) {        mediaip->s   = NULL;        mediaip->len = 0;        return 0;    }    zone.s = ptr + 2;    zone.len = findendline(zone.s, block->s + block->len - zone.s) - zone.s;    count = getStrTokens(&zone, tokens, 3);    if (count != 3) {        LOG(L_ERR, "error: mediaproxy/getMediaIPFromBlock(): invalid `c=' "            "line in SDP body\n");        return -1;    }    // can also check if tokens[1] == 'IP4'    *mediaip = tokens[2];    return 1;}// Get the session-level media IP defined by the SDP messagestatic BoolgetSessionLevelMediaIP(str *sdp, str *mediaip){    str block;    char *ptr;    // session IP can be found from the beginning up to the first media block    ptr = findLineStartingWith(sdp, "m=", False);    if (ptr) {        block.s   = sdp->s;        block.len = ptr - block.s;    } else {        block = *sdp;    }    if (getMediaIPFromBlock(&block, mediaip) == -1) {        LOG(L_ERR, "error: mediaproxy/getSessionLevelMediaIP(): parse error "            "while getting session-level media IP from SDP body\n");        return False;    }    // it's not an error to be missing. it can be locally defined    // by each media stream. thus we return true even if not found    return True;}// will get all media streamsstatic intgetMediaStreams(str *sdp, str *sessionIP, StreamInfo *streams, int limit){    str tokens[2], block, zone;    char *ptr, *sdpEnd;    int i, count, streamCount, result;    sdpEnd = sdp->s + sdp->len;    for (i=0, block=*sdp; i<limit; i++) {        ptr = findLineStartingWith(&block, "m=", False);        if (!ptr)            break;        zone.s = ptr + 2;        zone.len = findendline(zone.s, sdpEnd - zone.s) - zone.s;        count = getStrTokens(&zone, tokens, 2);        if (count != 2) {            LOG(L_ERR, "error: mediaproxy/getMediaStreams(): invalid `m=' "                "line in SDP body\n");            return -1;        }        streams[i].type = tokens[0];        streams[i].port = tokens[1];        block.s   = zone.s + zone.len;        block.len = sdpEnd - block.s;    }    streamCount = i;    for (i=0; i<streamCount; i++) {        block.s = streams[i].port.s;        if (i < streamCount-1)            block.len = streams[i+1].port.s - block.s;        else            block.len = sdpEnd - block.s;        result = getMediaIPFromBlock(&block, &(streams[i].ip));        if (result == -1) {            LOG(L_ERR, "error: mediaproxy/getMediaStreams(): parse error in "                "getting the contact IP for the media stream nr. %d\n", i+1);            return -1;        } else if (result == 0) {            if (sessionIP->s == NULL) {                LOG(L_ERR, "error: mediaproxy/getMediaStreams(): media stream "                    "doesn't define a contact IP and the session-level IP "                    "is missing\n");                return -1;            }            streams[i].ip = *sessionIP;            streams[i].localIP = 0;        } else {            streams[i].localIP = 1;        }    }    return streamCount;}static BoolreplaceElement(struct sip_msg *msg, str *oldElem, str *newElem){    struct lump* anchor;    char *buf;    if (newElem->len==oldElem->len &&        memcmp(newElem->s, oldElem->s, newElem->len)==0) {        return True;    }    buf = pkg_malloc(newElem->len);    if (!buf) {        LOG(L_ERR, "error: mediaproxy/replaceElement(): out of memory\n");        return False;    }    anchor = del_lump(msg, oldElem->s - msg->buf, oldElem->len, 0);    if (!anchor) {        LOG(L_ERR, "error: mediaproxy/replaceElement(): failed to delete old element\n");        pkg_free(buf);        return False;    }    memcpy(buf, newElem->s, newElem->len);    if (insert_new_lump_after(anchor, buf, newElem->len, 0)==0) {        LOG(L_ERR, "error: mediaproxy/replaceElement(): failed to insert new element\n");        pkg_free(buf);        return False;    }    return True;}// Functions dealing with the external mediaproxy helperstatic inline size_tuwrite(int fd, const void *buf, size_t count){    int len;    do        len = write(fd, buf, count);    while (len == -1 && errno == EINTR);    return len;}static inline size_turead(int fd, void *buf, size_t count){    int len;    do        len = read(fd, buf, count);    while (len == -1 && errno == EINTR);    return len;}static inline size_treadall(int fd, void *buf, size_t count){    int len, total;    for (len=0, total=0; count-total>0; total+=len) {        len = uread(fd, (char*)buf+total, count-total);        if (len == -1) {            return -1;        }        if (len == 0) {            break;        }    }    return total;}static char*sendMediaproxyCommand(char *command){    struct sockaddr_un addr;    int smpSocket, len;    static char buf[1024];    memset(&addr, 0, sizeof(addr));    addr.sun_family = AF_LOCAL;    strncpy(addr.sun_path, mediaproxySocket, sizeof(addr.sun_path) - 1);#ifdef HAVE_SOCKADDR_SA_LEN    addr.sun_len = strlen(addr.sun_path);#endif    smpSocket = socket(AF_LOCAL, SOCK_STREAM, 0);    if (smpSocket < 0) {        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't create socket\n");        return NULL;    }    if (connect(smpSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {        close(smpSocket);        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't connect to MediaProxy\n");        return NULL;    }    len = uwrite(smpSocket, command, strlen(command));    if (len <= 0) {        close(smpSocket);        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't send command to MediaProxy\n");        return NULL;    }    len = readall(smpSocket, buf, sizeof(buf)-1);    close(smpSocket);    if (len < 0) {        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't read reply from MediaProxy\n");        return NULL;    }    buf[len] = 0;    return buf;}// Miscellaneous helper functions/* Test if IP in `address' belongs to a RFC1918 network */static inline intrfc1918address(str *address){    struct in_addr inaddr;    uint32_t netaddr;    int i, result;    char c;    c = address->s[address->len];    address->s[address->len] = 0;    result = inet_aton(address->s, &inaddr);    address->s[address->len] = c;    if (result==0)        return -1; /* invalid address to test */    netaddr = ntohl(inaddr.s_addr);    for (i=0; rfc1918nets[i].name!=NULL; i++) {        if ((netaddr & rfc1918nets[i].mask)==rfc1918nets[i].address) {            return 1;        }    }    return 0;}#define isPrivateAddress(x) (rfc1918address(x)==1 ? 1 : 0)// test for a public address is more complex (also need to test for// address not in 0.0.0.0/8, 127.0.0.0/8, 224.0.0.0/4).// #define isPublicAddress(x)  (rfc1918address(x)==0 ? 1 : 0)// Check if the requested asymmetrics file has changed and reload it if neededstatic voidcheckAsymmetricFile(AsymmetricClients *aptr){    char buf[512], errbuf[256], *which;    regex_t *re, **regs;    int i, size, code;    Bool firstTime = False;    struct stat statbuf;    FILE *file;    str line;    if (stat(aptr->file, &statbuf) < 0)        return; // ignore missing file    if (statbuf.st_mtime <= aptr->timestamp)        return; // not changed    // now we have work to do    which = (aptr == &sipAsymmetrics ? "SIP" : "RTP");    if (!aptr->clients) {        // if we are here the first time allocate memory to hold the regexps

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -