记BFCP解析库confiance-v7bfcp-only-05中踩过的坑

更新时间:2023-07-08 16:02:06 阅读: 评论:0

记BFCP解析库confiance-v7bfcp-only-05中踩过的坑
1. 记BFCP解析库confiance-v7bfcp-only-05中踩过的坑
在开发sip呼叫辅流的过程中使⽤了⼀个bfcp的解析库:
然⽽在使⽤过程中发现这个解析库的⼀些缺陷,列举如下:
1.1. SUPPORTED-PRIMITIVES 和 SUPPORTED-ATTRIBUTES 的字节长度问题
原始库中对这两个字段的处理都是采⽤的unsigned short int存储到⽹络交互字节中,
根据
的描述,这两个字段都是占⽤1个字节的。
0                  1                  2                  3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 1 0 1 0|M|    Length    | Supp. Attr. |R| Supp. Attr. |R|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Supp. Attr. |R| Supp. Attr. |R| Supp. Attr. |R| Supp. Attr. |R|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                              |
/                                                              /
/                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              |            Padding            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 17: SUPPORTED-ATTRIBUTES format
0                  1                  2                  3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0 0 1 0 1 1|M|    Length    |  Primitive  |  Primitive  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Primitive  |  Primitive  |  Primitive  |  Primitive  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                              |
/                                                              /
/                              +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              |            Padding            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 18: SUPPORTED-PRIMITIVES format
1.2. Payload Length 的字节长度及单位问题
根据 描述
Payload Length: This 16-bit field contains the length of the message in 4-octet units, excluding the common header
由于bfcp要求⽹络交互字节块必须要以4字节对齐,凡是不⾜4字节的都需要填充。因此称为in 4-octet units,
octet 是指⼋个⽐特(bit)为⼀组的单位,通常是指⼀个字节(byte)的意思。
也就是说使⽤抓包⼯具查看bfcp的package时,Payload Length字段显⽰的值应该为整个BFCP包的长度减去BFCP通⽤头长度再除以4(即 (BFCPPackageLength - 12) / 4);相反的,在解析bfcp的pack
age时也要根据Payload Length字段的值乘以4再加上通⽤头长度即为整个包的长度(即 PayloadLength * 4 + 12) ,且应该对负载长度以4求余来校验字节块是否满⾜这⼀条件。
但原始库中对于这块的处理是有问题的,包括判断逻辑也有问题。
1.3. 关于va_arg的错误使⽤
在修改中引⼊了的这个问题,linux上使⽤解析库时引发异常
在使⽤ va_arg 时传⼊的可变参数会经历 默认参数提升 的隐式转换过程,因此在使⽤过程中ap的下⼀个参数类型不应该指定为以下类型:
char / signed char / unsigned char
short / signed short / unsigned short
short int / signed short int / unsigned short int
世好啤酒
有关c语⾔ 的规则描述如下:
默认参数提升
在函数调⽤表达式中,当调⽤下列函数时  1) ⽆原型函数
  2) 变参数函数,其中参数表达式是匹配省略号参数的尾随参数之⼀
每个整数类型的参数都会经历整数提升(见后述),⽽每个 float 类型参数都隐式转换为 double 类型
整数提升
整数提升是任何等级⼩于或等于 int 等级的整数类型,或是 _Bool 、 signed int 、 unsigned int 类型的位域类型的值到 int 或 unsigned int 类型值的隐式转换。若 int 能表⽰原类型的整个值域(或原位域的值域),则值转换成 int 类型。否则值转化成 unsigned int 类型。整数提升保持值,包含符号:
更详细的信息可参考:
1.4. 修改清单
详情参考:
左侧⽂件: 原始⽂件右侧⽂件: 修改后
1.4.1. bfcp_messages.h
1.4.
2. bfcp_messages.c
111typedef  struct  bfcp_floor_id_list { /* FLOOR-ID list, to manage the multiple FLOOR-ID attributes */
=111typedef  struct  bfcp_floor_id_list { /* FLOOR-ID list, to manage the multiple FLOOR-ID attributes */
112    unsigned  short  int  ID;          /* FLOOR-ID */
112    unsigned  short  int  ID;          /* FLOOR-ID */
113    struct  bfcp_floor_id_list *next;    /* Pointer to next FLOOR-ID instance */ 113    struct  bfcp_floor_id_list *next;    /* Pointer to next FLOOR-ID instance */114} bfcp_floor_id_list; 114} bfcp_floor_id_list;115
115
116typedef  struct  bfcp_supported_list {    /* list to manage all the supported attributes and primitives */
116typedef  struct  bfcp_supported_list {    /* list to manage all the supported attributes and primitives */
117    unsigned short  int  element;    /* Element (Attribute/Primitive) */<>117    unsigned char  element;      /* Element (Attribute/Primitive) */118    struct  bfcp_supported_list *next;  /* Pointer to next supported element instance */=118    struct  bfcp_supported_list *next;  /* Pointer to next supported element instance */119} bfcp_supported_list; 119} bfcp_supported_list;120
120
121typedef  struct  bfcp_request_status {
121typedef  struct  bfcp_request_status {
122    unsigned  short  int  rs;  /* Request Status */ 122    unsigned  short  int  rs;  /* Request Status */123
unsigned  short  int  qp;  /* Queue Position */
123
unsigned  short  int  qp;  /* Queue Position */
243/* Add IDs to an existing Floor ID list (last argument MUST be 0) */=243/* Add IDs to an existing Floor ID list (last argument MUST be 0)*/
244int  bfcp_add_floor_id_list(bfcp_floor_id_list *list, unsigned  short  int fID, ...);
244int  bfcp_add_floor_id_list(bfcp_floor_id_list *list, unsigned short  int  fID, ...);245/* Free a Floor ID list */
245/* Free a Floor ID list */
246int  bfcp_free_floor_id_list(bfcp_floor_id_list *list); 246int  bfcp_free_floor_id_list(bfcp_floor_id_list *list);247
247
248/* Create a new Supported (Primitives/Attributes) list (last argument MUST be 0) */
248/* Create a new Supported (Primitives/Attributes) list (last argument MUST be 0) */
249bfcp_supported_list *bfcp_new_supported_list(unsigned short  int element, ...);
<>249bfcp_supported_list *bfcp_new_supported_list(unsigned char element, ...);
250/* Free a Supported (Primitives/Attributes) list */=250/* Free a Supported (Primitives/Attributes) list */251int  bfcp_free_supported_list(bfcp_supported_list *list); 251int  bfcp_free_supported_list(bfcp_supported_list *list);252
252
253/* Create a New Request Status (RequestStatus/QueuePosition) */ 253/* Create a New Request Status (RequestStatus/QueuePosition)*/
254bfcp_request_status *bfcp_new_request_status(unsigned  short  int rs, unsigned  short  int  qp);
254bfcp_request_status *bfcp_new_request_status(unsigned short  int  rs, unsigned  short  int  qp);
255
/
* Free a Request Status (RequestStatus/QueuePosition) */
255
/* Free a Request Status (RequestStatus/QueuePosition) */
195
temp = next;
=
195
temp = next;
1.4.3. bfcp_messages_build.c
196    } 196    }197    return  0; 197    return  0;198} 198}199
199
200/* Create a new Supported (Primitives/Attributes) list (last argument MUST be 0) */
200/* Create a new Supported (Primitives/Attributes) list (last argument MUST be 0) */
201bfcp_supported_list *bfcp_new_supported_list(unsigned short  int element, ...)<>201bfcp_supported_list *bfcp_new_supported_list(unsigned char element, (202)
=202{
203    bfcp_supported_list *first, *previous, *next; 203    bfcp_supported_list *first, *previous, *next;204    va_list ap;
204    va_list ap;
205    va_start(ap, element);
205    va_start(ap, element);
206    first = calloc(1, sizeof (bfcp_supported_list));
206    first = calloc(1, sizeof (bfcp_supported_list));
207    if (!first)  /* We could not allocate the memory, return a with failure */
207    if (!first)  /* We could not allocate the memory, return a with failure */
208        return  NULL;
208        return  NULL;
209    first->element = element; 209    first->element = element;210    previous = first;
210    previous = first;
211    element = va_arg(ap, int);<>211    element = (unsigned  char)va_arg(ap, int);212    while (element) {无济于事什么意思
=212    while (element) {
213        next = calloc(1, sizeof (bfcp_supported_list));
213        next = calloc(1, sizeof (bfcp_supported_list));
214        if (!next)  /* We could not allocate the memory, return a with failure */
214        if (!next)  /* We could not allocate the memory, return a with failure */
215            return  NULL;
215            return  NULL;
216        next->element = element; 216        next->element = element;217        previous->next = next; 217        previous->next = next;218        previous = next;
218        previous = next;
219        element = va_arg(ap, int);<>219        element = (unsigned  char)va_arg(ap, int);220    }
=220    }
221    va_end(ap); 221    va_end(ap);222    return  first; 222    return  first;223} 223}224
224
225
/* Free a Supported (Primitives/Attributes) list */
225
/* Free a Supported (Primitives/Attributes) list */
45    unsigned  int  ch32;      /* 32 bits */=45    unsigned  int  ch32;      /* 32 bits */46    unsigned  short  int  ch16;    /* 16 bits */ 46    unsigned  short  int  ch16;    /* 16 bits */47    unsigned  char  *buffer = message->buffer; 47    unsigned  char  *buffer = message->buffer;
48    ch32 = (((ch32 & !(0xE0000000)) | (1)) << 29) +        /* First the Version (3 bits, t to 001) */
48    ch32 = (((ch32 & !(0xE0000000)) | (1)) << 29) +        /* First the Version (3bits, t to 001) */
49        (((ch32 & !(0x1F000000)) | (0)) << 24) +        /*then the Rerved (5 bits, ignored) */
49        (((ch32 & !(0x1F000000)) | (0)) << 24) +        /* then the Rerved (5 bits,ignored) */
50        (((ch32 & !(0x00FF0000)) | (primitive)) << 16) +  /* the Primitive (8 bits) */
50        (((ch32 & !(0x00FF0000)) | (primitive)) << 16) +    /* the Primitive (8 bits)*/
51        ((ch32 & !(0x0000FFFF)) | (message->length -12));  /* and the payload length (16 bits) */
<>51        ((ch32 & !(0x0000FFFF)) | ((message->length - 12) / 4));    /* and the payload length (16 bits), contains the length of the message in 4-octet units  */52    ch32 = htonl(ch32);    /* We want all protocol values in network-byte-order */=52    ch32 = htonl(ch32);    /* We want all protocol values in network-byte-order */53
memcpy(buffer, &ch32, 4);
53
memcpy(buffer, &ch32, 4);
54    buffer = buffer+4;54    buffer = buffer+4;
55    ch32 = htonl(entity->conferenceID);55    ch32 = htonl(entity->conferenceID);
56    memcpy(buffer, &ch32, 4);56    memcpy(buffer, &ch32, 4);
57    buffer = buffer+4;57    buffer = buffer+4;
497
if(!attributes) /* The supported attributes list is
empty, return with a failure */
=497if(!attributes) /* The supported attributes list is empty, return with a failure */
498return -1;498return -1;
499
int attrlen = 2;    /* The Lenght of the attribute
(starting from the TLV) */
499int attrlen = 2;    /* The Lenght of the attribute (starting from the TLV) */
500int padding = 0;    /* Number of bytes of padding */500int padding = 0;    /* Number of bytes of padding */
501
int position = message->position;      /* We keep
track of where the TLV will have to be */
501
int position = message->position;      /* We keep track of where the TLV will
have to be */
502
unsigned char *buffer =
message->buffer+(message->position)+2;  /* We skip
the TLV bytes */
502
unsigned char *buffer = message->buffer+(message->position)+2;  /* We
skip the TLV bytes */
503unsigned short int ch16;    /* 16 bits */+-
504    bfcp_supported_list *temp = attributes;=503    bfcp_supported_list *temp = attributes;空对空导弹打一成语是什么
505while(temp) {  /* Fill all supported attributes */504while(temp) {  /* Fill all supported attributes */ 506ch16 = htons(temp->element);<>505unsigned char ch = temp->element;
507memcpy(buffer,&ch16,2);506buffer[0]= ch<<1;
508        buffer = buffer+2;507        buffer = buffer+1;
509        attrlen = attrlen+2;508        attrlen = attrlen+1;
510        temp = temp->next;=509        temp = temp->next;
511    }510    }
512if((attrlen%4) != 0) {      /* We need padding */511if((attrlen%4) != 0) {      /* We need padding */ 513        padding = 4-(attrlen%4);512        padding = 4-(attrlen%4);
514        memt(buffer, 0, padding);513        memt(buffer, 0, padding);
515    }514    }
524
if(!primitives) /* The supported attributes list is
empty, return with a failure */
=523if(!primitives) /* The supported attributes list is empty, return with a failure */
525return -1;524return -1;
526
机械课程设计int attrlen = 2;    /* The Lenght of the attribute
(starting from the TLV) */
525int attrlen = 2;    /* The Lenght of the attribute (starting from the TLV) */
527int padding = 0;    /* Number of bytes of padding */526int padding = 0;    /* Number of bytes of padding */
528
int position = message->position;      /* We keep
北京射击场
track of where the TLV will have to be */
527
int position = message->position;      /* We keep track of where the TLV will
have to be */
529
unsigned char *buffer =
message->buffer+(message->position)+2;  /* We skip
the TLV bytes */
528
unsigned char *buffer = message->buffer+(message->position)+2;  /* We
skip the TLV bytes */
530unsigned short int ch16;    /* 16 bits */+-
531    bfcp_supported_list *temp = primitives;=529    bfcp_supported_list *temp = primitives;
532while(temp) {  /* Fill all supported primitives */530while(temp) {  /* Fill all supported primitives */ 533ch16 = htons(temp->element);<>531unsigned char ch = temp->element;
534memcpy(buffer, &ch16, 2);532memcpy(buffer, &ch, 1);
535        buffer = buffer+2;533        buffer = buffer+1;
536        attrlen = attrlen+2;534        attrlen = attrlen+1;
537        temp = temp->next;=535        temp = temp->next;
538    }536    }
1.4.4. bfcp_messages_par.c
539    if ((attrlen%4) != 0) {      /* We need padding */ 537    if ((attrlen%4) != 0) {      /* We need padding */540        padding = 4-(attrlen%4); 538        padding = 4-(attrlen%4);541        memt(buffer, 0, padding); 539        memt(buffer, 0, padding);542
}
540
}
190    if ((recvM->rerved) != 0) {    /* Rerved bits are not 0, return with an error */
=190    if ((recvM->rerved) != 0) {    /* Rerved bits are not 0, return with an error */
191        recvM->errors =
bfcp_received_message_add_error(recvM->errors, 0,BFCP_RESERVED_NOT_ZERO); 191        recvM->errors =
bfcp_received_message_add_error(recvM->errors, 0,BFCP_RESERVED_NOT_ZERO);192        if (!(recvM->errors))
192        if (!(recvM->errors))
193            return  NULL;    /* An error occurred while recording the error, return with failure */ 193            return  NULL;    /* An error occurred while recording the error, return with failure */194    }
194    }
195    recvM->primitive = ((ch32 & 0x00FF0000) >> 16); /* Primitive identifier */ 195    recvM->primitive = ((ch32 & 0x00FF0000) >> 16); /* Primitive identifier */
<>196    /* cau the Payload Lenght contains the length of the message in 4-octet units, here we need to multiple with 4 */
苏非196    recvM->length = (ch32 & 0x0000FFFF) + 12;  /* Payload Lenght of the message + 12 (Common Header) */
197    recvM->length = (ch32 & 0x0000FFFF) * 4 + 12;  /* Payload Lenght of the message + 12 (Common Header) */
197    if(((recvM->length ) != message->length) || !(recvM->length )%4){    /* The message length is wrong */
198    if((recvM->length != message->length) || (recvM->length  % 4)) {/* The message length is wrong */
198            /* Either the length in the header is different from the length of */
=199            /* Either the length in the header is different from the length of */
199            /*  ...or the length is not a multiple of 4, meaning it's surely not aligned */
200            /*  ...or the length is not a multiple of 4, meaning it's surely not aligned */
200        recvM->errors =
bfcp_received_message_add_error(recvM->errors, 0,BFCP_WRONG_LENGTH); 201        recvM->errors =
bfcp_received_message_add_error(recvM->errors, 0,BFCP_WRONG_LENGTH);201        if (!(recvM->errors))
202        if (!(recvM->errors))
202            return  NULL;    /* An error occurred while recording the error, return with failure */ 203            return  NULL;    /* An error occurred while recording the error, return with failure */203
}
204
}
621bfcp_supported_list
*bfcp_par_attribute_SUPPORTED_ATTRIBUTES(bfcp_message *message, bfcp_received_attribute *recvA)=622bfcp_supported_list
*bfcp_par_attribute_SUPPORTED_ATTRIBUTES(bfcp_message *message, bfcp_received_attribute *recvA)622{
623{
623    if (recvA->length<3) /* The length of this attribute is wrong */ 624    if (recvA->length<3) /* The length of this attribute is wrong */624        return  NULL; 625        return  NULL;625    int  i;
626    int  i;
626    bfcp_supported_list *first, *previous, *next; 627    bfcp_supported_list *first, *previous, *next;627    unsigned  short  int  ch16;    /* 16 bits */
+-
628    unsigned  char  *buffer = message->buffer+recvA->position+2; /* Skip the Header */
=628    unsigned  char  *buffer = message->buffer+recvA->position+2; /* Skip the Header */
629    int number = (recvA->length-2)/2;  /* Each supported attribute takes 2 bytes */<>629    int number = (recvA->length-2); /* Each supported attribute takes 1 bytes */630    if (!number)
=630    if (!number)
631        return  NULL;    /* No supported attributes? */ 631        return  NULL;    /* No supported attributes? */632    first = calloc(1, sizeof (bfcp_supported_list));
632    first = calloc(1, sizeof (bfcp_supported_list));
竹笋冻
633    if (!first)  /* An error occurred in creating a new Supported Attributes list */ 633    if (!first)  /* An error occurred in creating a new Supported Attributes list */634        return  NULL;
634        return  NULL;635    memcpy(&ch16, buffer, 2);<>
636    first->element = ntohs(ch16); 635    first->element = buffer[0] & 0xFE ;637    previous = first;
=636    previous = first;
638    if (number>1) {      /* Let's par each other supported attribute we find */
637    if (number>1) {      /* Let's par each other supported attribute we find */
639
巅峰官路
for (i = 1;i<number;i++) {
638
for (i = 1;i<number;i++) {

本文发布于:2023-07-08 16:02:06,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1085775.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:参数   类型   字节   长度
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图