sip里的via,record_route和route

本文详细介绍了HTTP中的Via、Route及Record-Route头部字段的作用及使用场景。Via字段用于指示交易中使用的传输方式,并标识响应发送的位置;Route字段用于强制请求通过指定的代理集进行路由;Record-Route字段由代理在请求中插入,以确保对话中的未来请求通过该代理。

      The Via header field indicates the transport used for the transaction  and identifies the location where the response is to be sent

      The Route header field is used to force routing for a request through
the listed set of proxies.

      via在请求的时候记录,回来response的时候弹出。route只在请求的时候找下一跳用到,他们不存在以谁为准的问题。

 

      The Record-Route header field is inserted by proxies in a request to force future requests in the dialog to be routed through the proxy.

      record-route没有必须填,这个是proxy插入的,目的是dialog在以后的请求经过自己。

#ifndef _SIP_PROTOCOL_H #define _SIP_PROTOCOL_H #include "common/sip_common.h" #ifdef SIP_USE_TCP #define SIP_TRANSPORT "TCP" #else #define SIP_TRANSPORT "UDP" #endif /* 字符数组长度宏定义 */ #define SIP_URI_SCHEME_LEN 8 #define SIP_URI_USER_LEN 32 #define SIP_URI_HOST_LEN 32 #define SIP_URI_PARAM_LEN 32 #define SIP_VIA_PROTOCOL_LEN 16 #define SIP_VIA_TRANSPORT_LEN 8 #define SIP_VIA_HOST_LEN 64 #define SIP_VIA_BRANCH_LEN 32 #define SIP_VIA_RECEIVED_LEN 32 #define AUTH_REALM_LEN 64 #define AUTH_NONCE_LEN 64 #define AUTH_ALGORITHM_LEN 32 #define AUTH_QOP_LEN 32 #define AUTH_OPAQUE_LEN 64 #define AUTH_RESPONSE_LEN 33 #define SIP_HEADER_CALLID_LEN 64 #define SIP_HEADER_CONTENT_TYPE_LEN 64 #define SIP_HEADER_CONTACT_LEN 64 #define SIP_HEADER_USER_AGENT_LEN 64 #define SIP_BODY_TYPE_LEN 32 #define SIP_REASON_PHRASE_LEN 32 #define SIP_CONFIG_USER_AGENT_LEN 32 #define SIP_BRANCH_LEN 32 #define SIP_TAG_LEN 32 #define SIP_CALLID_LEN 64 #define T1_TIMEOUT 500 #define T2_TIMEOUT 64 * T1_TIMEOUT #define T4_TIMEOUT 5000 /* SIP方法定义 */ typedef enum sip_method { SIP_METHOD_INVITE = 0, SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, SIP_METHOD_REGISTER, SIP_METHOD_OPTIONS, SIP_METHOD_MAX } sip_method; /* SIP响应状态码 */ /* SIP响应状态码枚举 (RFC 3261及相关扩展) */ typedef enum sip_status_code { /* 1xx 临时响应 */ SIP_100_TRYING = 100, SIP_180_RINGING = 180, SIP_181_CALL_IS_BEING_FORWARDED = 181, SIP_182_QUEUED = 182, SIP_183_SESSION_PROGRESS = 183, /* 2xx 成功响应 */ SIP_200_OK = 200, SIP_202_ACCEPTED = 202, // RFC3265 /* 3xx 重定向响应 */ SIP_300_MULTIPLE_CHOICES = 300, SIP_301_MOVED_PERMANENTLY = 301, SIP_302_MOVED_TEMPORARILY = 302, SIP_305_USE_PROXY = 305, SIP_380_ALTERNATIVE_SERVICE = 380, /* 4xx 客户端错误 */ SIP_400_BAD_REQUEST = 400, SIP_401_UNAUTHORIZED = 401, SIP_402_PAYMENT_REQUIRED = 402, SIP_403_FORBIDDEN = 403, SIP_404_NOT_FOUND = 404, SIP_405_METHOD_NOT_ALLOWED = 405, SIP_406_NOT_ACCEPTABLE = 406, SIP_407_PROXY_AUTHENTICATION_REQUIRED = 407, SIP_408_REQUEST_TIMEOUT = 408, SIP_410_GONE = 410, SIP_413_REQUEST_ENTITY_TOO_LARGE = 413, SIP_414_REQUEST_URI_TOO_LONG = 414, SIP_415_UNSUPPORTED_MEDIA_TYPE = 415, SIP_416_UNSUPPORTED_URI_SCHEME = 416, SIP_420_BAD_EXTENSION = 420, SIP_421_EXTENSION_REQUIRED = 421, SIP_423_INTERVAL_TOO_BRIEF = 423, SIP_480_TEMPORARILY_UNAVAILABLE = 480, SIP_481_CALL_TRANSACTION_DOES_NOT_EXIST = 481, SIP_482_LOOP_DETECTED = 482, SIP_483_TOO_MANY_HOPS = 483, SIP_484_ADDRESS_INCOMPLETE = 484, SIP_485_AMBIGUOUS = 485, SIP_486_BUSY_HERE = 486, SIP_487_REQUEST_TERMINATED = 487, SIP_488_NOT_ACCEPTABLE_HERE = 488, SIP_489_BAD_EVENT = 489, // RFC3265 SIP_491_REQUEST_PENDING = 491, SIP_493_UNDECIPHERABLE = 493, /* 5xx 服务器错误 */ SIP_500_SERVER_INTERNAL_ERROR = 500, SIP_501_NOT_IMPLEMENTED = 501, SIP_502_BAD_GATEWAY = 502, SIP_503_SERVICE_UNAVAILABLE = 503, SIP_504_SERVER_TIME_OUT = 504, SIP_505_VERSION_NOT_SUPPORTED = 505, SIP_513_MESSAGE_TOO_LARGE = 513, /* 6xx 全局错误 */ SIP_600_BUSY_EVERYWHERE = 600, SIP_603_DECLINE = 603, SIP_604_DOES_NOT_EXIST_ANYWHERE = 604, SIP_606_NOT_ACCEPTABLE = 606 } sip_status_code; /* SIP事务状态定义 */ typedef enum sip_transaction_state { Calling = 0, Trying, Proceeding, Completed, Terminated } sip_transaction_state; /* SIP URI结构 */ typedef struct sip_uri { char scheme[SIP_URI_SCHEME_LEN]; /* "sip" or "sips" */ char user[SIP_URI_USER_LEN]; /* username */ char host[SIP_URI_HOST_LEN]; /* domain or IP */ U16 port; /* port number */ char parameters[SIP_URI_PARAM_LEN]; /* URI parameters */ } sip_uri; /* SIP Via头结构 */ typedef struct sip_via { char protocol[SIP_VIA_PROTOCOL_LEN]; /* "SIP/2.0" */ char transport[SIP_VIA_TRANSPORT_LEN]; /* "UDP", "TCP" */ char host[SIP_VIA_HOST_LEN]; /* sent-by host */ U16 port; /* sent-by port */ char branch[SIP_VIA_BRANCH_LEN]; /* branch parameter */ char received[SIP_VIA_RECEIVED_LEN]; /* received parameter */ U16 rport; /* rport parameter */ } sip_via; /* 认证信息结构体 */ typedef struct auth_info_t { char realm[AUTH_REALM_LEN]; char nonce[AUTH_NONCE_LEN]; char algorithm[AUTH_ALGORITHM_LEN]; char qop[AUTH_QOP_LEN]; char opaque[AUTH_OPAQUE_LEN]; int stale; char response[AUTH_RESPONSE_LEN]; } auth_info_t; /* SIP消息头结构 */ typedef struct sip_headers { struct sip_uri from; /* From header */ struct sip_uri to; /* To header */ struct sip_via via; /* Via header */ char call_id[SIP_HEADER_CALLID_LEN]; /* Call-ID header */ U32 cseq; /* CSeq number */ enum sip_method cseq_method; /* CSeq method */ U8 max_forwards; /* Max-Forwards header */ char content_type[SIP_HEADER_CONTENT_TYPE_LEN]; /* Content-Type */ char contact[SIP_HEADER_CONTACT_LEN]; /* Contact header */ U32 content_length; /* Content-Length header */ U32 Expires; char user_agent[SIP_HEADER_USER_AGENT_LEN]; /* User-Agent */ auth_info_t auth; } sip_headers; /* SIP消息体结构 */ typedef struct sip_body { char *content; /* Message body content */ U32 length; /* Message body length */ char type[SIP_BODY_TYPE_LEN]; /* Content type */ } sip_body; /* SIP消息结构 */ typedef struct sip_message { U8 type; /* 0:request, 1:response */ enum sip_method method; /* Method (requests) */ U16 status_code; /* Status code (responses) */ char reason_phrase[SIP_REASON_PHRASE_LEN]; /* Reason phrase */ struct sip_uri request_uri; /* Request-URI */ struct sip_headers headers; /* SIP headers */ struct sip_body body; /* Message body */ struct sockaddr_in source; /* Message source */ struct list_head list; /* List head for queue */ } sip_message; /* SIP事务信息 */ typedef struct sip_transaction { char branch[SIP_BRANCH_LEN]; /* Transaction branch */ enum sip_method method; /* Transaction method */ int timeout_idx; struct sip_message *request; /* Original request */ struct sip_message *last_response; /* Last response */ sip_transaction_state state; /*0:off, 1:on*/ } sip_transaction; /* SIP对话信息 */ typedef struct sip_dialog { char remote_tag[SIP_URI_PARAM_LEN]; /* From */ char local_tag[SIP_URI_PARAM_LEN]; /* To */ char call_id[SIP_HEADER_CALLID_LEN]; } sip_dialog; /* 协议栈配置 */ typedef struct sip_protocol_config { char user_agent[SIP_CONFIG_USER_AGENT_LEN]; U8 max_forwards; U32 t1_timeout; /* T1 timer (RTT) */ U32 t2_timeout; /* T2 timer (64*T1) */ U32 t4_timeout; /* T4 timer (5000ms) */ } sip_protocol_config; /* SIP协议栈接口 */ /** * @brief SIP消息解析 * * @param[out] msg 解析出的sip消息 * * @param[in] data sip消息原始数据 * * @param[in] length 数据长度 * * @return 错误码 * */ int sip_message_parse(sip_message *msg, const char *data, U32 length); /** * @brief SIP消息解析 * * @param[in] msg sip消息结构体 * * @param[out] buffer 构造出的sip消息 * * @param[in] size 报文大小 * * @return 错误码 * */ int sip_message_build(sip_message *msg, char *buffer, U32 size); void sip_message_free(sip_message *msg); /** * @brief SIP消息拷贝 * * @param[in] src 源消息指针 * * @return sip消息指针 * */ sip_message *sip_message_copy(sip_message *src); int sip_uri_parse(sip_uri *uri, const char *uri_str); int sip_uri_build(sip_uri *uri, char *buffer, U32 size); /** * @brief 创建SIP事务 * * @param[ori_req] 源请求 * * @return SIP事务指针 * */ sip_transaction *sip_transaction_create(sip_message *ori_req, void *timeout_hanler); void sip_transaction_terminate(sip_transaction *trans); void sip_transaction_free(sip_transaction *trans); sip_dialog *sip_dialog_create(char *to_tag, char *from_tag, char *call_id); void sip_dialog_free(sip_dialog *dialog); const char *sip_method_to_string(enum sip_method method); sip_method sip_string_to_method(const char *method_str); const char *sip_status_to_reason(U16 status_code); void sip_generate_branch(char *branch, U32 size); void sip_generate_tag(char *tag, U32 size); void sip_generate_call_id(char *buf, int len); #endif /* _SIP_PROTOCOL_H */ 帮我改进一下对话事务的结构体,使逻辑更合理
11-14
/* 构建SIP消息 */ int sip_message_build(struct sip_message *msg, char *buffer, U32 size) { int pos = 0; char uri_buffer[256]; if (!msg || !buffer || size == 0) return -EINVAL; /* 构建起始行 */ if (msg->type == 0) { /* 请求行 */ sip_uri_build(&msg->request_uri, uri_buffer, sizeof(uri_buffer)); pos += snprintf(buffer + pos, size - pos, "%s %s", sip_method_to_string(msg->method), uri_buffer); if (msg->request_uri.parameters[0] != '\0') { pos += snprintf(buffer + pos, size - pos, ";%s", msg->request_uri.parameters); } pos += snprintf(buffer + pos, size - pos, " SIP/2.0\r\n"); } else { /* 状态行 */ const char *reason = sip_status_to_reason(msg->status_code); pos += snprintf(buffer + pos, size - pos, "SIP/2.0 %hu %s\r\n", msg->status_code, reason ? reason : "Unknown"); } /* 构建Via头 */ if (msg->headers.via.host[0] != '\0') { pos += snprintf(buffer + pos, size - pos, "Via: %s/%s %s:%hu", msg->headers.via.protocol, msg->headers.via.transport, msg->headers.via.host, msg->headers.via.port); if (msg->headers.via.branch[0] != '\0') { pos += snprintf(buffer + pos, size - pos, ";branch=%s", msg->headers.via.branch); } pos += snprintf(buffer + pos, size - pos, ";rport"); pos += snprintf(buffer + pos, size - pos, "\r\n"); } /* 构建Contact头 */ pos += snprintf(buffer + pos, size - pos, msg->headers.contact); /* 构建To头 */ sip_uri_build(&msg->headers.to, uri_buffer, sizeof(uri_buffer)); pos += snprintf(buffer + pos, size - pos, "To: <%s>", uri_buffer); /* 添加To tag(如果有) */ if (msg->headers.to.parameters[0] != '\0') { pos += snprintf(buffer + pos, size - pos, ";tag=%s", msg->headers.to.parameters); } pos += snprintf(buffer + pos, size - pos, "\r\n"); /* 构建From头 */ sip_uri_build(&msg->headers.from, uri_buffer, sizeof(uri_buffer)); pos += snprintf(buffer + pos, size - pos, "From: <%s>", uri_buffer); /* 添加From tag(如果有) */ if (msg->headers.from.parameters[0] != '\0') { pos += snprintf(buffer + pos, size - pos, ";tag=%s", msg->headers.from.parameters); } pos += snprintf(buffer + pos, size - pos, "\r\n"); /* 请求行 */ sip_uri_build(&msg->request_uri, uri_buffer, sizeof(uri_buffer)); /* 构建Authorize头 */ if (strlen(msg->headers.auth.nonce) > 0) { pos += snprintf(buffer + pos, size - pos, "Authorization: Digest username=\"%s\",realm=\"%s\", nonce=\"%s\", uri=\"sip:%s\", response=\"%s\",algorithm=%s\r\n", msg->headers.from.user, msg->headers.auth.realm, msg->headers.auth.nonce, msg->headers.auth.realm, msg->headers.auth.response, "MD5"); } /* 构建Call-ID头 */ pos += snprintf(buffer + pos, size - pos, "Call-ID: %s\r\n", msg->headers.call_id); /* 构建CSeq头 */ pos += snprintf(buffer + pos, size - pos, "CSeq: %u %s\r\n", msg->headers.cseq, sip_method_to_string(msg->headers.cseq_method)); /* 构建Expires头 */ if (msg->headers.Expires) { pos += snprintf(buffer + pos, size - pos, "Expires: %u\r\n", msg->headers.Expires); } /* 构建Max-Forwards头 */ pos += snprintf(buffer + pos, size - pos, "Max-Forwards: %hhu\r\n", msg->headers.max_forwards); /* 构建User-Agent头 */ if (msg->headers.user_agent[0] != '\0') { pos += snprintf(buffer + pos, size - pos, "User-Agent: %s\r\n", msg->headers.user_agent); } /* 构建Content-Type头(如果有消息体) */ if (msg->body.length > 0) { pos += snprintf(buffer + pos, size - pos, "Content-Type: %s\r\n", msg->body.type); } /* 构建Content-Length头 */ pos += snprintf(buffer + pos, size - pos, "Content-Length: %u\r\n", msg->body.length); /* 空行分隔头部消息体 */ pos += snprintf(buffer + pos, size - pos, "\r\n"); /* 添加消息体 */ if (msg->body.length > 0 && msg->body.content) { if (pos + msg->body.length < size) { memcpy(buffer + pos, msg->body.content, msg->body.length); pos += msg->body.length; } } return pos; }给这个函数增加record route的处理逻辑,以及via头部的处理逻辑需要修改,因为可能存在多个via条目
11-21
/* 解析SIP消息 */ int sip_message_parse(struct sip_message *msg, const char *data, U32 length) { char *line, *saveptr; char *data_copy; if (!msg || !data || length == 0) return -EINVAL; sip_message_init(msg); /* 复制消息数据 */ data_copy = malloc(length + 1); if (!data_copy) return -ENOMEM; memcpy(data_copy, data, length); data_copy[length] = '\0'; /* 解析起始行 */ line = strtok_r(data_copy, "\r\n", &saveptr); if (!line) { free(data_copy); return -EINVAL; } /* 判断消息类型 */ if (strncmp(line, "SIP/2.0", 7) == 0) { /* 响应消息 */ msg->type = 1; if (sscanf(line, "SIP/2.0 %hu", &msg->status_code) == 1) { /* 提取原因短语 */ char *reason_start = strchr(line, ' '); if (reason_start) { reason_start = strchr(reason_start + 1, ' '); if (reason_start) { strlcpy(msg->reason_phrase, reason_start + 1, sizeof(msg->reason_phrase)); } } } } else { /* 请求消息 */ msg->type = 0; /* 提取方法 */ char method_str[16]; if (sscanf(line, "%15s", method_str) == 1) { msg->method = sip_string_to_method(method_str); } /* 提取Request-URI */ char *uri_start = strchr(line, ' '); if (uri_start) { char *uri_end = strchr(uri_start + 1, ' '); if (uri_end) { char uri[256]; U32 uri_len = uri_end - uri_start - 1; if (uri_len < sizeof(uri)) { strncpy(uri, uri_start + 1, uri_len); uri[uri_len] = '\0'; sip_uri_parse(&msg->request_uri, uri); } } } } /* 解析头部字段 */ while ((line = strtok_r(NULL, "\r\n", &saveptr)) != NULL) { if (strlen(line) == 0) { break; /* 空行,头部结束 */ } if (strncasecmp(line, "From:", 5) == 0) { char *uri_start = strchr(line, '<'); if (uri_start) { char *uri_end = strchr(uri_start + 1, '>'); if (uri_end) { char uri[256]; U32 uri_len = uri_end - uri_start - 1; if (uri_len < sizeof(uri)) { strncpy(uri, uri_start + 1, uri_len); uri[uri_len] = '\0'; sip_uri_parse(&msg->headers.from, uri); } } char *tag_start = strstr(uri_end, ";tag="); if (tag_start) { tag_start += 5; // 跳过";tag=" char *tag_end = tag_start; while (*tag_end && *tag_end != ';' && *tag_end != ' ' && *tag_end != '\r' && *tag_end != '\n') { tag_end++; } size_t tag_len = tag_end - tag_start; if (tag_len > 0 && tag_len < sizeof(msg->headers.from.parameters)) { strncpy(msg->headers.from.parameters, tag_start, tag_len); msg->headers.from.parameters[tag_len] = '\0'; } } } } else if (strncasecmp(line, "To:", 3) == 0) { char *uri_start = strchr(line, '<'); if (uri_start) { char *uri_end = strchr(uri_start + 1, '>'); if (uri_end) { char uri[256]; U32 uri_len = uri_end - uri_start - 1; if (uri_len < sizeof(uri)) { strncpy(uri, uri_start + 1, uri_len); uri[uri_len] = '\0'; sip_uri_parse(&msg->headers.to, uri); } } char *tag_start = strstr(uri_end, ";tag="); if (tag_start) { tag_start += 5; // 跳过";tag=" char *tag_end = tag_start; while (*tag_end && *tag_end != ';' && *tag_end != ' ' && *tag_end != '\r' && *tag_end != '\n') { tag_end++; } size_t tag_len = tag_end - tag_start; if (tag_len > 0 && tag_len < sizeof(msg->headers.to.parameters)) { strncpy(msg->headers.to.parameters, tag_start, tag_len); msg->headers.to.parameters[tag_len] = '\0'; } } } } else if (strncasecmp(line, "Contact:", 8) == 0) { char *uri_start = strchr(line, '<'); if (uri_start) { char *uri_end = strchr(uri_start + 1, '>'); if (uri_end) { char uri[256]; U32 uri_len = uri_end - uri_start - 1; if (uri_len < sizeof(uri)) { sip_uri *contact = malloc(sizeof(sip_uri)); strncpy(uri, uri_start + 1, uri_len); uri[uri_len] = '\0'; sip_uri_parse(contact, uri); memset(contact,0,sizeof(sip_uri)); sip_uri_parse(contact, uri); INIT_LIST_HEAD(&contact->list); list_add_tail(&contact->list, &msg->headers.contact); } } } } else if (strncasecmp(line, "Call-ID:", 8) == 0) { char *id_start = line + 8; while (*id_start == ' ') id_start++; strlcpy(msg->headers.call_id, id_start, sizeof(msg->headers.call_id)); } else if (strncasecmp(line, "Expires:", 8) == 0) { msg->headers.Expires = strtoul(line + 8, NULL, 10); } else if (strncasecmp(line, "CSeq:", 5) == 0) { char method_str[16]; if (sscanf(line + 5, "%u %15s", &msg->headers.cseq, method_str) == 2) { msg->headers.cseq_method = sip_string_to_method(method_str); } } else if (strncasecmp(line, "Content-Type:", 13) == 0) { char *type_start = line + 13; while (*type_start == ' ') type_start++; strlcpy(msg->headers.content_type, type_start, sizeof(msg->headers.content_type)); } else if (strncasecmp(line, "Content-Length:", 15) == 0) { msg->headers.content_length = strtoul(line + 15, NULL, 10); } else if (strncasecmp(line, "Via:", 4) == 0) { /* 创建临时存储结构 */ struct sip_via *via_temp = malloc(sizeof(sip_via)); memset(via_temp,0,sizeof(sip_via)); char *via_start = line + 4; while (*via_start == ' ' || *via_start == '\t') via_start++; // 跳过空白 /* 提取协议传输层 */ char *slash = strchr(via_start, '/'); if (slash) { size_t proto_len = slash - via_start; if (proto_len < sizeof(via_temp->protocol)) { strncpy(via_temp->protocol, via_start, proto_len); via_temp->protocol[proto_len] = '\0'; } char *space = strchr(slash + 1, ' '); if (space) { size_t trans_len = space - (slash + 1); if (trans_len < sizeof(via_temp->transport)) { strncpy(via_temp->transport, slash + 1, trans_len); via_temp->transport[trans_len] = '\0'; } via_start = space + 1; } } /* 提取主机地址 */ char *host_start = via_start; char *host_end = strchr(host_start, ';'); if (!host_end) host_end = strchr(host_start, ':'); if (!host_end) host_end = strchr(host_start, ' '); if (!host_end) host_end = host_start + strlen(host_start); if (host_end > host_start) { size_t host_len = host_end - host_start; if (host_len < sizeof(via_temp->host)) { strncpy(via_temp->host, host_start, host_len); via_temp->host[host_len] = '\0'; } via_start = host_end; } /* 提取端口号 (如果有) */ if (*via_start == ':') { via_temp->port = (U16)atoi(via_start + 1); } else { via_temp->port = 5060; // 默认SIP端口 } /* 提取参数 (branch, received, rport) */ char *params_start = strchr(via_start, ';'); while (params_start) { params_start++; // 跳过';' if (strncasecmp(params_start, "branch=", 7) == 0) { char *value = params_start + 7; char *end = strpbrk(value, ";\r\n "); size_t len = end ? (end - value) : strlen(value); if (len < sizeof(via_temp->branch)) { strncpy(via_temp->branch, value, len); via_temp->branch[len] = '\0'; } } else if (strncasecmp(params_start, "received=", 9) == 0) { char *value = params_start + 9; char *end = strpbrk(value, ";\r\n "); size_t len = end ? (end - value) : strlen(value); if (len < sizeof(via_temp->received)) { strncpy(via_temp->received, value, len); via_temp->received[len] = '\0'; } } else if (strncasecmp(params_start, "rport", 5) == 0) { char *eq = strchr(params_start, '='); if (eq) { via_temp->rport = (U16)atoi(eq + 1); } else { via_temp->rport = 0; // 标记存在rport但无值 } } // 移动到下一个参数 params_start = strpbrk(params_start, ";"); } INIT_LIST_HEAD(&via_temp->list); list_add_tail(&via_temp->list, &msg->headers.vias); } /* 在解析头部字段的循环中添加 Record-Route 分支 */ else if (strncasecmp(line, "Record-Route:", 13) == 0) { char *uri_start = strchr(line, '<'); if (uri_start) { char *uri_end = strchr(uri_start + 1, '>'); if (uri_end) { char uri[256]; U32 uri_len = uri_end - uri_start - 1; if (uri_len < sizeof(uri)) { strncpy(uri, uri_start + 1, uri_len); uri[uri_len] = '\0'; sip_uri *uri_tmp=malloc(sizeof(sip_uri)); sip_uri_parse(uri_tmp, uri); INIT_LIST_HEAD(&uri_tmp->list); list_add_tail(&uri_tmp->list, &msg->headers.record_route); } } } } else if (strncasecmp(line, "WWW-Authenticate: Digest", 24) == 0) { char *ptr = line + 24, *key, *value; while (*ptr != '\r') { // 跳过空格逗号 while (*ptr == ' ' || *ptr == ',') ptr++; // 提取键 key = ptr; while (*ptr && *ptr != '=') ptr++; if (*ptr != '=') break; *ptr++ = '\0'; // 提取值 if (*ptr == '"') { ptr++; value = ptr; while (*ptr && *ptr != '"') ptr++; if (*ptr == '"') *ptr++ = '\0'; } else { value = ptr; while (*ptr && *ptr != ' ' && *ptr != ',') ptr++; if (*ptr) *ptr++ = '\0'; } // 保存参数 if (strcmp(key, "realm") == 0) { strncpy(msg->headers.auth.realm, value, sizeof(msg->headers.auth.realm) - 1); } else if (strcmp(key, "nonce") == 0) { strncpy(msg->headers.auth.nonce, value, sizeof(msg->headers.auth.nonce) - 1); } else if (strcmp(key, "algorithm") == 0) { strncpy(msg->headers.auth.algorithm, value, sizeof(msg->headers.auth.algorithm) - 1); } else if (strcmp(key, "qop") == 0) { strncpy(msg->headers.auth.qop, value, sizeof(msg->headers.auth.qop) - 1); } else if (strcmp(key, "opaque") == 0) { strncpy(msg->headers.auth.opaque, value, sizeof(msg->headers.auth.opaque) - 1); } else if (strcmp(key, "stale") == 0) { msg->headers.auth.stale = (strcmp(value, "true") == 0); } } } } /* 解析消息体 */ if (msg->headers.content_length > 0) { char *body_start = strstr(data, "\r\n\r\n"); if (body_start) { body_start += 4; /* 跳过空行 */ msg->body.content = malloc(msg->headers.content_length); #ifdef MALLOC_PRINT SIP_ERROR("malloc trans: %d\n", msg->headers.content_length); #endif if (msg->body.content) { memcpy(msg->body.content, body_start, msg->headers.content_length); msg->body.content[msg->headers.content_length] = '\0'; msg->body.length = msg->headers.content_length; strlcpy(msg->body.type, msg->headers.content_type, sizeof(msg->body.type)); } } } free(data_copy); return 0; } /* SIP方法定义 */ typedef enum sip_method { SIP_METHOD_INVITE = 0, SIP_METHOD_ACK, SIP_METHOD_BYE, SIP_METHOD_CANCEL, SIP_METHOD_REGISTER, SIP_METHOD_MAX } sip_method; 增加一段解析allow的程序
最新发布
11-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值