werift 0.22.9 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +46 -0
  2. package/lib/common/src/transport.d.ts +22 -9
  3. package/lib/common/src/transport.js +152 -25
  4. package/lib/common/src/transport.js.map +1 -1
  5. package/lib/dtls/src/flight/server/flight6.js +12 -2
  6. package/lib/dtls/src/flight/server/flight6.js.map +1 -1
  7. package/lib/dtls/src/server.js +6 -1
  8. package/lib/dtls/src/server.js.map +1 -1
  9. package/lib/dtls/src/socket.d.ts +1 -0
  10. package/lib/dtls/src/socket.js +3 -0
  11. package/lib/dtls/src/socket.js.map +1 -1
  12. package/lib/ice/src/candidate.d.ts +16 -1
  13. package/lib/ice/src/candidate.js +99 -15
  14. package/lib/ice/src/candidate.js.map +1 -1
  15. package/lib/ice/src/ice.d.ts +2 -0
  16. package/lib/ice/src/ice.js +171 -41
  17. package/lib/ice/src/ice.js.map +1 -1
  18. package/lib/ice/src/iceBase.d.ts +23 -2
  19. package/lib/ice/src/iceBase.js +63 -1
  20. package/lib/ice/src/iceBase.js.map +1 -1
  21. package/lib/ice/src/index.d.ts +2 -0
  22. package/lib/ice/src/index.js +2 -0
  23. package/lib/ice/src/index.js.map +1 -1
  24. package/lib/ice/src/stun/const.d.ts +1 -26
  25. package/lib/ice/src/stun/const.js +15 -54
  26. package/lib/ice/src/stun/const.js.map +1 -1
  27. package/lib/ice/src/stun/message.d.ts +1 -25
  28. package/lib/ice/src/stun/message.js +15 -149
  29. package/lib/ice/src/stun/message.js.map +1 -1
  30. package/lib/ice/src/stun/protocol.d.ts +1 -1
  31. package/lib/ice/src/stun/protocol.js +2 -2
  32. package/lib/ice/src/stun/protocol.js.map +1 -1
  33. package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
  34. package/lib/ice/src/stun/tcpFrame.js +26 -0
  35. package/lib/ice/src/stun/tcpFrame.js.map +1 -0
  36. package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
  37. package/lib/ice/src/stun/tcpProtocol.js +326 -0
  38. package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
  39. package/lib/ice/src/stun/transaction.d.ts +2 -1
  40. package/lib/ice/src/stun/transaction.js +9 -3
  41. package/lib/ice/src/stun/transaction.js.map +1 -1
  42. package/lib/ice/src/turn/frame.d.ts +1 -0
  43. package/lib/ice/src/turn/frame.js +18 -0
  44. package/lib/ice/src/turn/frame.js.map +1 -0
  45. package/lib/ice/src/turn/protocol.d.ts +9 -7
  46. package/lib/ice/src/turn/protocol.js +32 -44
  47. package/lib/ice/src/turn/protocol.js.map +1 -1
  48. package/lib/ice/src/types/model.d.ts +1 -1
  49. package/lib/ice/src/types/model.js.map +1 -1
  50. package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
  51. package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
  52. package/lib/ice-server/src/stun/attributes.js.map +1 -0
  53. package/lib/ice-server/src/stun/const.d.ts +28 -0
  54. package/lib/ice-server/src/stun/const.js +88 -0
  55. package/lib/ice-server/src/stun/const.js.map +1 -0
  56. package/lib/ice-server/src/stun/message.d.ts +37 -0
  57. package/lib/ice-server/src/stun/message.js +190 -0
  58. package/lib/ice-server/src/stun/message.js.map +1 -0
  59. package/lib/ice-server/src/turn/auth.d.ts +1 -0
  60. package/lib/ice-server/src/turn/auth.js +10 -0
  61. package/lib/ice-server/src/turn/auth.js.map +1 -0
  62. package/lib/ice-server/src/turn/frame.d.ts +13 -0
  63. package/lib/ice-server/src/turn/frame.js +69 -0
  64. package/lib/ice-server/src/turn/frame.js.map +1 -0
  65. package/lib/index.mjs +3075 -883
  66. package/lib/nonstandard/index.mjs +1964 -447
  67. package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
  68. package/lib/rtp/src/extra/container/mp4/container.js +258 -173
  69. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  70. package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
  71. package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
  72. package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
  73. package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
  74. package/lib/rtp/src/extra/processor/mp4.js +115 -60
  75. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  76. package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
  77. package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
  78. package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
  79. package/lib/rtp/src/index.d.ts +1 -0
  80. package/lib/rtp/src/index.js +1 -0
  81. package/lib/rtp/src/index.js.map +1 -1
  82. package/lib/rtp/src/srtp/cipher/ctr.d.ts +3 -3
  83. package/lib/rtp/src/srtp/cipher/ctr.js +25 -14
  84. package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
  85. package/lib/rtp/src/srtp/cipher/gcm.d.ts +3 -3
  86. package/lib/rtp/src/srtp/cipher/gcm.js +57 -20
  87. package/lib/rtp/src/srtp/cipher/gcm.js.map +1 -1
  88. package/lib/rtp/src/srtp/cipher/index.d.ts +1 -1
  89. package/lib/rtp/src/srtp/cipher/index.js +1 -1
  90. package/lib/rtp/src/srtp/cipher/index.js.map +1 -1
  91. package/lib/rtp/src/srtp/context/srtp.d.ts +2 -1
  92. package/lib/rtp/src/srtp/context/srtp.js +22 -5
  93. package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
  94. package/lib/rtp/src/srtp/error.d.ts +3 -0
  95. package/lib/rtp/src/srtp/error.js +11 -0
  96. package/lib/rtp/src/srtp/error.js.map +1 -0
  97. package/lib/rtp/src/srtp/packet.d.ts +5 -0
  98. package/lib/rtp/src/srtp/packet.js +48 -0
  99. package/lib/rtp/src/srtp/packet.js.map +1 -0
  100. package/lib/webrtc/src/dataChannel.d.ts +4 -2
  101. package/lib/webrtc/src/dataChannel.js +14 -4
  102. package/lib/webrtc/src/dataChannel.js.map +1 -1
  103. package/lib/webrtc/src/errors.d.ts +3 -0
  104. package/lib/webrtc/src/errors.js +11 -0
  105. package/lib/webrtc/src/errors.js.map +1 -0
  106. package/lib/webrtc/src/helper.d.ts +5 -1
  107. package/lib/webrtc/src/helper.js +33 -1
  108. package/lib/webrtc/src/helper.js.map +1 -1
  109. package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
  110. package/lib/webrtc/src/media/receiver/statistics.js +22 -0
  111. package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
  112. package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
  113. package/lib/webrtc/src/media/rtpReceiver.js +135 -20
  114. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  115. package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
  116. package/lib/webrtc/src/media/rtpSender.js +177 -28
  117. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  118. package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
  119. package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
  120. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  121. package/lib/webrtc/src/media/stats.d.ts +15 -1
  122. package/lib/webrtc/src/media/stats.js +55 -1
  123. package/lib/webrtc/src/media/stats.js.map +1 -1
  124. package/lib/webrtc/src/media/track.d.ts +2 -1
  125. package/lib/webrtc/src/media/track.js +7 -1
  126. package/lib/webrtc/src/media/track.js.map +1 -1
  127. package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
  128. package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
  129. package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
  130. package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
  131. package/lib/webrtc/src/nonstandard/navigator.js +96 -32
  132. package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
  133. package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
  134. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
  135. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
  136. package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
  137. package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
  138. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  139. package/lib/webrtc/src/peerConnection.d.ts +185 -49
  140. package/lib/webrtc/src/peerConnection.js +477 -107
  141. package/lib/webrtc/src/peerConnection.js.map +1 -1
  142. package/lib/webrtc/src/sctpManager.d.ts +2 -2
  143. package/lib/webrtc/src/sctpManager.js +30 -9
  144. package/lib/webrtc/src/sctpManager.js.map +1 -1
  145. package/lib/webrtc/src/sdp.d.ts +10 -7
  146. package/lib/webrtc/src/sdp.js +39 -9
  147. package/lib/webrtc/src/sdp.js.map +1 -1
  148. package/lib/webrtc/src/sdpManager.d.ts +5 -4
  149. package/lib/webrtc/src/sdpManager.js +53 -31
  150. package/lib/webrtc/src/sdpManager.js.map +1 -1
  151. package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
  152. package/lib/webrtc/src/secureTransportManager.js +101 -23
  153. package/lib/webrtc/src/secureTransportManager.js.map +1 -1
  154. package/lib/webrtc/src/transceiverManager.d.ts +5 -4
  155. package/lib/webrtc/src/transceiverManager.js +64 -64
  156. package/lib/webrtc/src/transceiverManager.js.map +1 -1
  157. package/lib/webrtc/src/transport/dtls.d.ts +16 -4
  158. package/lib/webrtc/src/transport/dtls.js +208 -35
  159. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  160. package/lib/webrtc/src/transport/ice.d.ts +21 -3
  161. package/lib/webrtc/src/transport/ice.js +159 -30
  162. package/lib/webrtc/src/transport/ice.js.map +1 -1
  163. package/lib/webrtc/src/transport/sctp.d.ts +10 -3
  164. package/lib/webrtc/src/transport/sctp.js +44 -13
  165. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  166. package/lib/webrtc/src/utils.d.ts +14 -4
  167. package/lib/webrtc/src/utils.js +138 -16
  168. package/lib/webrtc/src/utils.js.map +1 -1
  169. package/package.json +7 -4
  170. package/lib/ice/src/stun/attributes.js.map +0 -1
  171. package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
  172. package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
  173. package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.methods = exports.classes = exports.AttributeKeys = exports.RETRY_RTO = exports.RETRY_MAX = exports.IPV6_PROTOCOL = exports.IPV4_PROTOCOL = exports.INTEGRITY_LENGTH = exports.HEADER_LENGTH = exports.FINGERPRINT_XOR = exports.FINGERPRINT_LENGTH = exports.COOKIE = void 0;
4
+ exports.isComprehensionRequiredAttribute = isComprehensionRequiredAttribute;
5
+ exports.isStunMessage = isStunMessage;
6
+ exports.COOKIE = 0x2112a442;
7
+ exports.FINGERPRINT_LENGTH = 8;
8
+ exports.FINGERPRINT_XOR = 0x5354554e;
9
+ exports.HEADER_LENGTH = 20;
10
+ exports.INTEGRITY_LENGTH = 24;
11
+ exports.IPV4_PROTOCOL = 1;
12
+ exports.IPV6_PROTOCOL = 2;
13
+ exports.RETRY_MAX = 6;
14
+ exports.RETRY_RTO = 50;
15
+ exports.AttributeKeys = [
16
+ "FINGERPRINT",
17
+ "MESSAGE-INTEGRITY",
18
+ "MESSAGE-INTEGRITY-SHA256",
19
+ "CHANGE-REQUEST",
20
+ "PRIORITY",
21
+ "USERNAME",
22
+ "USERHASH",
23
+ "ICE-CONTROLLING",
24
+ "SOURCE-ADDRESS",
25
+ "USE-CANDIDATE",
26
+ "ICE-CONTROLLED",
27
+ "ERROR-CODE",
28
+ "UNKNOWN-ATTRIBUTES",
29
+ "XOR-MAPPED-ADDRESS",
30
+ "CHANGED-ADDRESS",
31
+ "LIFETIME",
32
+ "REQUESTED-TRANSPORT",
33
+ "NONCE",
34
+ "REALM",
35
+ "REQUESTED-ADDRESS-FAMILY",
36
+ "EVEN-PORT",
37
+ "PASSWORD-ALGORITHM",
38
+ "PASSWORD-ALGORITHMS",
39
+ "XOR-RELAYED-ADDRESS",
40
+ "RESERVATION-TOKEN",
41
+ "CHANNEL-NUMBER",
42
+ "XOR-PEER-ADDRESS",
43
+ "DATA",
44
+ "SOFTWARE",
45
+ "MAPPED-ADDRESS",
46
+ "ALTERNATE-DOMAIN",
47
+ "ALTERNATE-SERVER",
48
+ "RESPONSE-ORIGIN",
49
+ "OTHER-ADDRESS",
50
+ ];
51
+ var classes;
52
+ (function (classes) {
53
+ classes[classes["REQUEST"] = 0] = "REQUEST";
54
+ classes[classes["INDICATION"] = 16] = "INDICATION";
55
+ classes[classes["RESPONSE"] = 256] = "RESPONSE";
56
+ classes[classes["ERROR"] = 272] = "ERROR";
57
+ })(classes || (exports.classes = classes = {}));
58
+ var methods;
59
+ (function (methods) {
60
+ methods[methods["BINDING"] = 1] = "BINDING";
61
+ methods[methods["SHARED_SECRET"] = 2] = "SHARED_SECRET";
62
+ methods[methods["ALLOCATE"] = 3] = "ALLOCATE";
63
+ methods[methods["REFRESH"] = 4] = "REFRESH";
64
+ methods[methods["SEND"] = 6] = "SEND";
65
+ methods[methods["DATA"] = 7] = "DATA";
66
+ methods[methods["CREATE_PERMISSION"] = 8] = "CREATE_PERMISSION";
67
+ methods[methods["CHANNEL_BIND"] = 9] = "CHANNEL_BIND";
68
+ })(methods || (exports.methods = methods = {}));
69
+ function isComprehensionRequiredAttribute(type) {
70
+ return type >= 0x0000 && type <= 0x7fff;
71
+ }
72
+ function isStunMessage(data) {
73
+ if (data.length < exports.HEADER_LENGTH) {
74
+ return false;
75
+ }
76
+ if ((data[0] & 0xc0) !== 0) {
77
+ return false;
78
+ }
79
+ if (data.readUInt32BE(4) !== exports.COOKIE) {
80
+ return false;
81
+ }
82
+ const length = data.readUInt16BE(2);
83
+ if (length % 4 !== 0) {
84
+ return false;
85
+ }
86
+ return data.length === exports.HEADER_LENGTH + length;
87
+ }
88
+ //# sourceMappingURL=const.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"const.js","sourceRoot":"","sources":["../../../../../ice-server/src/stun/const.ts"],"names":[],"mappings":";;;AAkEA,4EAEC;AAED,sCAmBC;AAzFY,QAAA,MAAM,GAAG,UAAU,CAAC;AACpB,QAAA,kBAAkB,GAAG,CAAC,CAAC;AACvB,QAAA,eAAe,GAAG,UAAU,CAAC;AAC7B,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,gBAAgB,GAAG,EAAE,CAAC;AACtB,QAAA,aAAa,GAAG,CAAC,CAAC;AAClB,QAAA,aAAa,GAAG,CAAC,CAAC;AAElB,QAAA,SAAS,GAAG,CAAC,CAAC;AACd,QAAA,SAAS,GAAG,EAAE,CAAC;AAEf,QAAA,aAAa,GAAG;IAC3B,aAAa;IACb,mBAAmB;IACnB,0BAA0B;IAC1B,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,UAAU;IACV,iBAAiB;IACjB,gBAAgB;IAChB,eAAe;IACf,gBAAgB;IAChB,YAAY;IACZ,oBAAoB;IACpB,oBAAoB;IACpB,iBAAiB;IACjB,UAAU;IACV,qBAAqB;IACrB,OAAO;IACP,OAAO;IACP,0BAA0B;IAC1B,WAAW;IACX,oBAAoB;IACpB,qBAAqB;IACrB,qBAAqB;IACrB,mBAAmB;IACnB,gBAAgB;IAChB,kBAAkB;IAClB,MAAM;IACN,UAAU;IACV,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,iBAAiB;IACjB,eAAe;CACP,CAAC;AAEX,IAAY,OAKX;AALD,WAAY,OAAO;IACjB,2CAAe,CAAA;IACf,kDAAkB,CAAA;IAClB,+CAAgB,CAAA;IAChB,yCAAa,CAAA;AACf,CAAC,EALW,OAAO,uBAAP,OAAO,QAKlB;AAED,IAAY,OASX;AATD,WAAY,OAAO;IACjB,2CAAa,CAAA;IACb,uDAAmB,CAAA;IACnB,6CAAc,CAAA;IACd,2CAAa,CAAA;IACb,qCAAU,CAAA;IACV,qCAAU,CAAA;IACV,+DAAuB,CAAA;IACvB,qDAAkB,CAAA;AACpB,CAAC,EATW,OAAO,uBAAP,OAAO,QASlB;AAED,SAAgB,gCAAgC,CAAC,IAAY;IAC3D,OAAO,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC;AAC1C,CAAC;AAED,SAAgB,aAAa,CAAC,IAAY;IACxC,IAAI,IAAI,CAAC,MAAM,GAAG,qBAAa,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,cAAM,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,KAAK,qBAAa,GAAG,MAAM,CAAC;AAChD,CAAC","sourcesContent":["export const COOKIE = 0x2112a442;\nexport const FINGERPRINT_LENGTH = 8;\nexport const FINGERPRINT_XOR = 0x5354554e;\nexport const HEADER_LENGTH = 20;\nexport const INTEGRITY_LENGTH = 24;\nexport const IPV4_PROTOCOL = 1;\nexport const IPV6_PROTOCOL = 2;\n\nexport const RETRY_MAX = 6;\nexport const RETRY_RTO = 50;\n\nexport const AttributeKeys = [\n \"FINGERPRINT\",\n \"MESSAGE-INTEGRITY\",\n \"MESSAGE-INTEGRITY-SHA256\",\n \"CHANGE-REQUEST\",\n \"PRIORITY\",\n \"USERNAME\",\n \"USERHASH\",\n \"ICE-CONTROLLING\",\n \"SOURCE-ADDRESS\",\n \"USE-CANDIDATE\",\n \"ICE-CONTROLLED\",\n \"ERROR-CODE\",\n \"UNKNOWN-ATTRIBUTES\",\n \"XOR-MAPPED-ADDRESS\",\n \"CHANGED-ADDRESS\",\n \"LIFETIME\",\n \"REQUESTED-TRANSPORT\",\n \"NONCE\",\n \"REALM\",\n \"REQUESTED-ADDRESS-FAMILY\",\n \"EVEN-PORT\",\n \"PASSWORD-ALGORITHM\",\n \"PASSWORD-ALGORITHMS\",\n \"XOR-RELAYED-ADDRESS\",\n \"RESERVATION-TOKEN\",\n \"CHANNEL-NUMBER\",\n \"XOR-PEER-ADDRESS\",\n \"DATA\",\n \"SOFTWARE\",\n \"MAPPED-ADDRESS\",\n \"ALTERNATE-DOMAIN\",\n \"ALTERNATE-SERVER\",\n \"RESPONSE-ORIGIN\",\n \"OTHER-ADDRESS\",\n] as const;\n\nexport enum classes {\n REQUEST = 0x000,\n INDICATION = 0x010,\n RESPONSE = 0x100,\n ERROR = 0x110,\n}\n\nexport enum methods {\n BINDING = 0x1,\n SHARED_SECRET = 0x2,\n ALLOCATE = 0x3,\n REFRESH = 0x4,\n SEND = 0x6,\n DATA = 0x7,\n CREATE_PERMISSION = 0x8,\n CHANNEL_BIND = 0x9,\n}\n\nexport function isComprehensionRequiredAttribute(type: number) {\n return type >= 0x0000 && type <= 0x7fff;\n}\n\nexport function isStunMessage(data: Buffer) {\n if (data.length < HEADER_LENGTH) {\n return false;\n }\n\n if ((data[0] & 0xc0) !== 0) {\n return false;\n }\n\n if (data.readUInt32BE(4) !== COOKIE) {\n return false;\n }\n\n const length = data.readUInt16BE(2);\n if (length % 4 !== 0) {\n return false;\n }\n\n return data.length === HEADER_LENGTH + length;\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import { type AttributePair, AttributeRepository, type RawAttribute } from "./attributes";
2
+ import { type classes, type methods } from "./const";
3
+ export declare function parseMessage(data: Buffer, integrityKey?: Buffer): Message | undefined;
4
+ export declare class Message extends AttributeRepository {
5
+ messageMethod: methods;
6
+ messageClass: classes;
7
+ transactionId: Buffer;
8
+ rawAttributes: RawAttribute[];
9
+ constructor(messageMethod: methods, messageClass: classes, transactionId?: Buffer, attributes?: AttributePair[], rawAttributes?: RawAttribute[]);
10
+ toJSON(): {
11
+ messageMethod: methods;
12
+ messageClass: classes;
13
+ attributes: AttributePair[];
14
+ rawAttributes: {
15
+ type: number;
16
+ length: number;
17
+ }[];
18
+ };
19
+ get json(): {
20
+ messageMethod: methods;
21
+ messageClass: classes;
22
+ attributes: AttributePair[];
23
+ rawAttributes: {
24
+ type: number;
25
+ length: number;
26
+ }[];
27
+ };
28
+ get transactionIdHex(): string;
29
+ appendRawAttribute(type: number, value: Buffer): this;
30
+ get unknownAttributeTypes(): number[];
31
+ get bytes(): Buffer<ArrayBuffer>;
32
+ addMessageIntegrity(key: Buffer): this;
33
+ messageIntegrity(key: Buffer): Buffer<ArrayBuffer>;
34
+ addFingerprint(): this;
35
+ private get serializedAttributes();
36
+ }
37
+ export declare function paddingLength(length: number): number;
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Message = void 0;
4
+ exports.parseMessage = parseMessage;
5
+ exports.paddingLength = paddingLength;
6
+ const crypto_1 = require("crypto");
7
+ const src_1 = require("../../../common/src");
8
+ const attributes_1 = require("./attributes");
9
+ const const_1 = require("./const");
10
+ function parseMessage(data, integrityKey) {
11
+ if (!(0, const_1.isStunMessage)(data)) {
12
+ return undefined;
13
+ }
14
+ const messageType = data.readUInt16BE(0);
15
+ const transactionId = Buffer.from(data.slice(const_1.HEADER_LENGTH - 12, const_1.HEADER_LENGTH));
16
+ const attributeRepository = new attributes_1.AttributeRepository();
17
+ const rawAttributes = [];
18
+ for (let pos = const_1.HEADER_LENGTH; pos < data.length;) {
19
+ if (pos + 4 > data.length) {
20
+ return undefined;
21
+ }
22
+ const attrType = data.readUInt16BE(pos);
23
+ const attrLen = data.readUInt16BE(pos + 2);
24
+ const valueStart = pos + 4;
25
+ const valueEnd = valueStart + attrLen;
26
+ if (valueEnd > data.length) {
27
+ return undefined;
28
+ }
29
+ const payload = data.slice(valueStart, valueEnd);
30
+ const padLen = paddingLength(attrLen);
31
+ if (valueEnd + padLen > data.length) {
32
+ return undefined;
33
+ }
34
+ const attribute = attributes_1.ATTRIBUTES_BY_TYPE[attrType];
35
+ if (attribute) {
36
+ const [, attrName, , attrUnpack] = attribute;
37
+ let value;
38
+ try {
39
+ value =
40
+ attrUnpack.name === attributes_1.unpackXorAddress.name
41
+ ? attrUnpack(payload, transactionId)
42
+ : attrUnpack(payload);
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ attributeRepository.setAttribute(attrName, value);
48
+ if (attrName === "FINGERPRINT") {
49
+ const fingerprint = messageFingerprint(data.slice(0, pos));
50
+ if (attributeRepository.getAttributeValue("FINGERPRINT") !== fingerprint) {
51
+ return undefined;
52
+ }
53
+ }
54
+ else if (attrName === "MESSAGE-INTEGRITY" && integrityKey) {
55
+ const integrity = messageIntegrity(data.slice(0, pos), integrityKey);
56
+ const expected = attributeRepository.getAttributeValue("MESSAGE-INTEGRITY");
57
+ if (!integrity.equals(expected)) {
58
+ return undefined;
59
+ }
60
+ }
61
+ }
62
+ else {
63
+ rawAttributes.push({
64
+ type: attrType,
65
+ length: attrLen,
66
+ value: Buffer.from(payload),
67
+ });
68
+ }
69
+ pos = valueEnd + padLen;
70
+ }
71
+ return new Message(messageType & 0x3eef, messageType & 0x0110, transactionId, attributeRepository.getAttributes(), rawAttributes);
72
+ }
73
+ class Message extends attributes_1.AttributeRepository {
74
+ constructor(messageMethod, messageClass, transactionId = (0, crypto_1.randomBytes)(12), attributes = [], rawAttributes = []) {
75
+ super(attributes);
76
+ Object.defineProperty(this, "messageMethod", {
77
+ enumerable: true,
78
+ configurable: true,
79
+ writable: true,
80
+ value: messageMethod
81
+ });
82
+ Object.defineProperty(this, "messageClass", {
83
+ enumerable: true,
84
+ configurable: true,
85
+ writable: true,
86
+ value: messageClass
87
+ });
88
+ Object.defineProperty(this, "transactionId", {
89
+ enumerable: true,
90
+ configurable: true,
91
+ writable: true,
92
+ value: transactionId
93
+ });
94
+ Object.defineProperty(this, "rawAttributes", {
95
+ enumerable: true,
96
+ configurable: true,
97
+ writable: true,
98
+ value: rawAttributes
99
+ });
100
+ }
101
+ toJSON() {
102
+ return this.json;
103
+ }
104
+ get json() {
105
+ return {
106
+ messageMethod: this.messageMethod,
107
+ messageClass: this.messageClass,
108
+ attributes: this.attributes,
109
+ rawAttributes: this.rawAttributes.map((attribute) => ({
110
+ type: attribute.type,
111
+ length: attribute.value.length,
112
+ })),
113
+ };
114
+ }
115
+ get transactionIdHex() {
116
+ return this.transactionId.toString("hex");
117
+ }
118
+ appendRawAttribute(type, value) {
119
+ this.rawAttributes.push({ type, value: Buffer.from(value) });
120
+ return this;
121
+ }
122
+ get unknownAttributeTypes() {
123
+ return this.rawAttributes.map((attribute) => attribute.type);
124
+ }
125
+ get bytes() {
126
+ const body = Buffer.concat(this.serializedAttributes.map((attribute) => serializeAttribute(attribute.type, attribute.value)));
127
+ const header = Buffer.alloc(8);
128
+ header.writeUInt16BE(this.messageMethod | this.messageClass, 0);
129
+ header.writeUInt16BE(body.length, 2);
130
+ header.writeUInt32BE(const_1.COOKIE, 4);
131
+ return Buffer.concat([header, this.transactionId, body]);
132
+ }
133
+ addMessageIntegrity(key) {
134
+ this.setAttribute("MESSAGE-INTEGRITY", this.messageIntegrity(key));
135
+ return this;
136
+ }
137
+ messageIntegrity(key) {
138
+ const checkData = setBodyLength(this.bytes, this.bytes.length - const_1.HEADER_LENGTH + const_1.INTEGRITY_LENGTH);
139
+ return Buffer.from((0, crypto_1.createHmac)("sha1", key).update(checkData).digest("hex"), "hex");
140
+ }
141
+ addFingerprint() {
142
+ this.setAttribute("FINGERPRINT", messageFingerprint(this.bytes));
143
+ return this;
144
+ }
145
+ get serializedAttributes() {
146
+ const attributes = [];
147
+ for (const attrName of this.attributesKeys) {
148
+ const attrValue = this.getAttributeValue(attrName);
149
+ const [attrType, , attrPack] = attributes_1.ATTRIBUTES_BY_NAME[attrName];
150
+ const value = attrPack.name === attributes_1.packXorAddress.name
151
+ ? attrPack(attrValue, this.transactionId)
152
+ : attrPack(attrValue);
153
+ attributes.push({ type: attrType, value });
154
+ }
155
+ attributes.push(...this.rawAttributes.map((attribute) => ({
156
+ type: attribute.type,
157
+ value: Buffer.from(attribute.value),
158
+ })));
159
+ return attributes;
160
+ }
161
+ }
162
+ exports.Message = Message;
163
+ function serializeAttribute(type, value) {
164
+ const attrLen = value.length;
165
+ const padLen = paddingLength(attrLen);
166
+ const header = Buffer.alloc(4);
167
+ header.writeUInt16BE(type, 0);
168
+ header.writeUInt16BE(attrLen, 2);
169
+ return Buffer.concat([header, value, Buffer.alloc(padLen)]);
170
+ }
171
+ const setBodyLength = (data, length) => {
172
+ const output = Buffer.alloc(data.length);
173
+ data.copy(output, 0, 0, 2);
174
+ output.writeUInt16BE(length, 2);
175
+ data.copy(output, 4, 4);
176
+ return output;
177
+ };
178
+ function messageFingerprint(data) {
179
+ const checkData = setBodyLength(data, data.length - const_1.HEADER_LENGTH + const_1.FINGERPRINT_LENGTH);
180
+ return ((0, src_1.crc32)(checkData) ^ const_1.FINGERPRINT_XOR) >>> 0;
181
+ }
182
+ function messageIntegrity(data, key) {
183
+ const checkData = setBodyLength(data, data.length - const_1.HEADER_LENGTH + const_1.INTEGRITY_LENGTH);
184
+ return Buffer.from((0, crypto_1.createHmac)("sha1", key).update(checkData).digest("hex"), "hex");
185
+ }
186
+ function paddingLength(length) {
187
+ const rest = length % 4;
188
+ return rest === 0 ? 0 : 4 - rest;
189
+ }
190
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../../../ice-server/src/stun/message.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHmac, randomBytes } from \"crypto\";\n\nimport { crc32 } from \"../../../common/src\";\n\nimport {\n ATTRIBUTES_BY_NAME,\n ATTRIBUTES_BY_TYPE,\n type AttributeKey,\n type AttributePair,\n AttributeRepository,\n type RawAttribute,\n packXorAddress,\n unpackXorAddress,\n} from \"./attributes\";\nimport {\n COOKIE,\n FINGERPRINT_LENGTH,\n FINGERPRINT_XOR,\n HEADER_LENGTH,\n INTEGRITY_LENGTH,\n type classes,\n isStunMessage,\n type methods,\n} from \"./const\";\n\nexport function parseMessage(\n data: Buffer,\n integrityKey?: Buffer,\n): Message | undefined {\n if (!isStunMessage(data)) {\n return undefined;\n }\n\n const messageType = data.readUInt16BE(0);\n const transactionId = Buffer.from(\n data.slice(HEADER_LENGTH - 12, HEADER_LENGTH),\n );\n\n const attributeRepository = new AttributeRepository();\n const rawAttributes: RawAttribute[] = [];\n\n for (let pos = HEADER_LENGTH; pos < data.length; ) {\n if (pos + 4 > data.length) {\n return undefined;\n }\n\n const attrType = data.readUInt16BE(pos);\n const attrLen = data.readUInt16BE(pos + 2);\n const valueStart = pos + 4;\n const valueEnd = valueStart + attrLen;\n\n if (valueEnd > data.length) {\n return undefined;\n }\n\n const payload = data.slice(valueStart, valueEnd);\n const padLen = paddingLength(attrLen);\n if (valueEnd + padLen > data.length) {\n return undefined;\n }\n\n const attribute = ATTRIBUTES_BY_TYPE[attrType];\n if (attribute) {\n const [, attrName, , attrUnpack] = attribute;\n let value: unknown;\n try {\n value =\n attrUnpack.name === unpackXorAddress.name\n ? attrUnpack(payload, transactionId)\n : attrUnpack(payload);\n } catch {\n return undefined;\n }\n attributeRepository.setAttribute(attrName as AttributeKey, value);\n\n if (attrName === \"FINGERPRINT\") {\n const fingerprint = messageFingerprint(data.slice(0, pos));\n if (\n attributeRepository.getAttributeValue(\"FINGERPRINT\") !== fingerprint\n ) {\n return undefined;\n }\n } else if (attrName === \"MESSAGE-INTEGRITY\" && integrityKey) {\n const integrity = messageIntegrity(data.slice(0, pos), integrityKey);\n const expected =\n attributeRepository.getAttributeValue(\"MESSAGE-INTEGRITY\");\n if (!integrity.equals(expected)) {\n return undefined;\n }\n }\n } else {\n rawAttributes.push({\n type: attrType,\n length: attrLen,\n value: Buffer.from(payload),\n });\n }\n\n pos = valueEnd + padLen;\n }\n\n return new Message(\n messageType & 0x3eef,\n messageType & 0x0110,\n transactionId,\n attributeRepository.getAttributes(),\n rawAttributes,\n );\n}\n\nexport class Message extends AttributeRepository {\n constructor(\n public messageMethod: methods,\n public messageClass: classes,\n public transactionId: Buffer = randomBytes(12),\n attributes: AttributePair[] = [],\n public rawAttributes: RawAttribute[] = [],\n ) {\n super(attributes);\n }\n\n toJSON() {\n return this.json;\n }\n\n get json() {\n return {\n messageMethod: this.messageMethod,\n messageClass: this.messageClass,\n attributes: this.attributes,\n rawAttributes: this.rawAttributes.map((attribute) => ({\n type: attribute.type,\n length: attribute.value.length,\n })),\n };\n }\n\n get transactionIdHex() {\n return this.transactionId.toString(\"hex\");\n }\n\n appendRawAttribute(type: number, value: Buffer) {\n this.rawAttributes.push({ type, value: Buffer.from(value) });\n return this;\n }\n\n get unknownAttributeTypes() {\n return this.rawAttributes.map((attribute) => attribute.type);\n }\n\n get bytes() {\n const body = Buffer.concat(\n this.serializedAttributes.map((attribute) =>\n serializeAttribute(attribute.type, attribute.value),\n ),\n );\n\n const header = Buffer.alloc(8);\n header.writeUInt16BE(this.messageMethod | this.messageClass, 0);\n header.writeUInt16BE(body.length, 2);\n header.writeUInt32BE(COOKIE, 4);\n\n return Buffer.concat([header, this.transactionId, body]);\n }\n\n addMessageIntegrity(key: Buffer) {\n this.setAttribute(\"MESSAGE-INTEGRITY\", this.messageIntegrity(key));\n return this;\n }\n\n messageIntegrity(key: Buffer) {\n const checkData = setBodyLength(\n this.bytes,\n this.bytes.length - HEADER_LENGTH + INTEGRITY_LENGTH,\n );\n return Buffer.from(\n createHmac(\"sha1\", key).update(checkData).digest(\"hex\"),\n \"hex\",\n );\n }\n\n addFingerprint() {\n this.setAttribute(\"FINGERPRINT\", messageFingerprint(this.bytes));\n return this;\n }\n\n private get serializedAttributes() {\n const attributes: RawAttribute[] = [];\n\n for (const attrName of this.attributesKeys) {\n const attrValue = this.getAttributeValue(attrName);\n const [attrType, , attrPack] = ATTRIBUTES_BY_NAME[attrName];\n const value =\n attrPack.name === packXorAddress.name\n ? attrPack(attrValue, this.transactionId)\n : attrPack(attrValue);\n attributes.push({ type: attrType, value });\n }\n\n attributes.push(\n ...this.rawAttributes.map((attribute) => ({\n type: attribute.type,\n value: Buffer.from(attribute.value),\n })),\n );\n\n return attributes;\n }\n}\n\nfunction serializeAttribute(type: number, value: Buffer) {\n const attrLen = value.length;\n const padLen = paddingLength(attrLen);\n const header = Buffer.alloc(4);\n header.writeUInt16BE(type, 0);\n header.writeUInt16BE(attrLen, 2);\n return Buffer.concat([header, value, Buffer.alloc(padLen)]);\n}\n\nconst setBodyLength = (data: Buffer, length: number) => {\n const output = Buffer.alloc(data.length);\n data.copy(output, 0, 0, 2);\n output.writeUInt16BE(length, 2);\n data.copy(output, 4, 4);\n return output;\n};\n\nfunction messageFingerprint(data: Buffer) {\n const checkData = setBodyLength(\n data,\n data.length - HEADER_LENGTH + FINGERPRINT_LENGTH,\n );\n return (crc32(checkData) ^ FINGERPRINT_XOR) >>> 0;\n}\n\nfunction messageIntegrity(data: Buffer, key: Buffer) {\n const checkData = setBodyLength(\n data,\n data.length - HEADER_LENGTH + INTEGRITY_LENGTH,\n );\n return Buffer.from(\n createHmac(\"sha1\", key).update(checkData).digest(\"hex\"),\n \"hex\",\n );\n}\n\nexport function paddingLength(length: number) {\n const rest = length % 4;\n return rest === 0 ? 0 : 4 - rest;\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function makeTurnIntegrityKey(username: string, realm: string, password: string): Buffer<ArrayBufferLike>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeTurnIntegrityKey = makeTurnIntegrityKey;
4
+ const crypto_1 = require("crypto");
5
+ function makeTurnIntegrityKey(username, realm, password) {
6
+ return (0, crypto_1.createHash)("md5")
7
+ .update(Buffer.from([username, realm, password].join(":")))
8
+ .digest();
9
+ }
10
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../../ice-server/src/turn/auth.ts"],"names":[],"mappings":";;AAEA,oDAQC;AAVD,mCAAoC;AAEpC,SAAgB,oBAAoB,CAClC,QAAgB,EAChB,KAAa,EACb,QAAgB;IAEhB,OAAO,IAAA,mBAAU,EAAC,KAAK,CAAC;SACrB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;SAC1D,MAAM,EAAE,CAAC;AACd,CAAC","sourcesContent":["import { createHash } from \"crypto\";\n\nexport function makeTurnIntegrityKey(\n username: string,\n realm: string,\n password: string,\n) {\n return createHash(\"md5\")\n .update(Buffer.from([username, realm, password].join(\":\")))\n .digest();\n}\n"]}
@@ -0,0 +1,13 @@
1
+ export interface ChannelDataMessage {
2
+ channelNumber: number;
3
+ data: Buffer;
4
+ }
5
+ export declare function isChannelData(data: Buffer): boolean;
6
+ export declare function encodeChannelData(channelNumber: number, data: Buffer): Buffer<ArrayBuffer>;
7
+ export declare function decodeChannelData(data: Buffer): ChannelDataMessage | undefined;
8
+ export declare function padTurnFrame(data: Buffer): Buffer<ArrayBufferLike>;
9
+ export declare function splitTurnTcpFrames(buffer: Buffer): {
10
+ frames: Buffer<ArrayBufferLike>[];
11
+ malformed: boolean;
12
+ rest: Buffer<ArrayBufferLike>;
13
+ };
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isChannelData = isChannelData;
4
+ exports.encodeChannelData = encodeChannelData;
5
+ exports.decodeChannelData = decodeChannelData;
6
+ exports.padTurnFrame = padTurnFrame;
7
+ exports.splitTurnTcpFrames = splitTurnTcpFrames;
8
+ const message_1 = require("../stun/message");
9
+ function isChannelData(data) {
10
+ return data.length >= 4 && (data[0] & 0xc0) === 0x40;
11
+ }
12
+ function encodeChannelData(channelNumber, data) {
13
+ const header = Buffer.alloc(4);
14
+ header.writeUInt16BE(channelNumber, 0);
15
+ header.writeUInt16BE(data.length, 2);
16
+ return Buffer.concat([header, data]);
17
+ }
18
+ function decodeChannelData(data) {
19
+ if (!isChannelData(data) || data.length < 4) {
20
+ return undefined;
21
+ }
22
+ const channelNumber = data.readUInt16BE(0);
23
+ const length = data.readUInt16BE(2);
24
+ if (data.length < 4 + length) {
25
+ return undefined;
26
+ }
27
+ return {
28
+ channelNumber,
29
+ data: data.subarray(4, 4 + length),
30
+ };
31
+ }
32
+ function padTurnFrame(data) {
33
+ const padding = (0, message_1.paddingLength)(data.length);
34
+ return padding > 0 ? Buffer.concat([data, Buffer.alloc(padding)]) : data;
35
+ }
36
+ function splitTurnTcpFrames(buffer) {
37
+ const frames = [];
38
+ let offset = 0;
39
+ let malformed = false;
40
+ while (buffer.length - offset >= 4) {
41
+ let frameLength;
42
+ if (isChannelData(buffer.subarray(offset))) {
43
+ const payloadLength = buffer.readUInt16BE(offset + 2);
44
+ frameLength = 4 + payloadLength + (0, message_1.paddingLength)(payloadLength);
45
+ }
46
+ else if ((buffer[offset] & 0xc0) === 0) {
47
+ if (buffer.length - offset < 20) {
48
+ break;
49
+ }
50
+ const stunBodyLength = buffer.readUInt16BE(offset + 2);
51
+ frameLength = 20 + stunBodyLength + (0, message_1.paddingLength)(stunBodyLength);
52
+ }
53
+ else {
54
+ malformed = true;
55
+ break;
56
+ }
57
+ if (buffer.length - offset < frameLength) {
58
+ break;
59
+ }
60
+ frames.push(buffer.subarray(offset, offset + frameLength));
61
+ offset += frameLength;
62
+ }
63
+ return {
64
+ frames,
65
+ malformed,
66
+ rest: buffer.subarray(offset),
67
+ };
68
+ }
69
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../../../../ice-server/src/turn/frame.ts"],"names":[],"mappings":"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","sourcesContent":["import { paddingLength } from \"../stun/message\";\n\nexport interface ChannelDataMessage {\n channelNumber: number;\n data: Buffer;\n}\n\nexport function isChannelData(data: Buffer) {\n return data.length >= 4 && (data[0] & 0xc0) === 0x40;\n}\n\nexport function encodeChannelData(channelNumber: number, data: Buffer) {\n const header = Buffer.alloc(4);\n header.writeUInt16BE(channelNumber, 0);\n header.writeUInt16BE(data.length, 2);\n return Buffer.concat([header, data]);\n}\n\nexport function decodeChannelData(\n data: Buffer,\n): ChannelDataMessage | undefined {\n if (!isChannelData(data) || data.length < 4) {\n return undefined;\n }\n\n const channelNumber = data.readUInt16BE(0);\n const length = data.readUInt16BE(2);\n if (data.length < 4 + length) {\n return undefined;\n }\n\n return {\n channelNumber,\n data: data.subarray(4, 4 + length),\n };\n}\n\nexport function padTurnFrame(data: Buffer) {\n const padding = paddingLength(data.length);\n return padding > 0 ? Buffer.concat([data, Buffer.alloc(padding)]) : data;\n}\n\nexport function splitTurnTcpFrames(buffer: Buffer) {\n const frames: Buffer[] = [];\n let offset = 0;\n let malformed = false;\n\n while (buffer.length - offset >= 4) {\n let frameLength: number;\n\n if (isChannelData(buffer.subarray(offset))) {\n const payloadLength = buffer.readUInt16BE(offset + 2);\n frameLength = 4 + payloadLength + paddingLength(payloadLength);\n } else if ((buffer[offset] & 0xc0) === 0) {\n if (buffer.length - offset < 20) {\n break;\n }\n const stunBodyLength = buffer.readUInt16BE(offset + 2);\n frameLength = 20 + stunBodyLength + paddingLength(stunBodyLength);\n } else {\n malformed = true;\n break;\n }\n\n if (buffer.length - offset < frameLength) {\n break;\n }\n\n frames.push(buffer.subarray(offset, offset + frameLength));\n offset += frameLength;\n }\n\n return {\n frames,\n malformed,\n rest: buffer.subarray(offset),\n };\n}\n"]}