Skip to content

Commit 6d915fa

Browse files
committed
support Multiple Handshake Message
1 parent a72b8c6 commit 6d915fa

File tree

3 files changed

+71
-49
lines changed

3 files changed

+71
-49
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"ci": "run-s type:all build test doc",
2424
"clean": "rm -rf packages/*/node_modules",
2525
"datachannel": "ts-node-dev examples/datachannel/offer.ts",
26+
"debug": "DEBUG=werift* tsx watch examples/mediachannel/sendrecv/answer.ts",
2627
"doc": "npm run doc --workspaces --if-present && rm -rf doc && cd packages/webrtc && mv doc ../..",
2728
"e2e": "cd e2e && npm run ci:silent",
2829
"e2e:verbose": "cd e2e && npm run ci",

packages/dtls/src/record/receive.ts

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ export const parsePacket = (data: Buffer) => {
1414
const packets: DtlsPlaintext[] = [];
1515
while (data.length > start) {
1616
const fragmentLength = data.readUInt16BE(start + 11);
17-
if (data.length < start + (12 + fragmentLength)) break;
18-
const packet = DtlsPlaintext.deSerialize(data.slice(start));
17+
if (data.length < start + (12 + fragmentLength)) {
18+
break;
19+
}
20+
const packet = DtlsPlaintext.deSerialize(data.subarray(start));
1921
packets.push(packet);
2022

2123
start += 13 + fragmentLength;
@@ -25,16 +27,24 @@ export const parsePacket = (data: Buffer) => {
2527
};
2628

2729
export const parsePlainText =
28-
(dtls: DtlsContext, cipher: CipherContext) => (plain: DtlsPlaintext) => {
30+
(dtls: DtlsContext, cipher: CipherContext) =>
31+
(
32+
plain: DtlsPlaintext,
33+
): {
34+
type: ContentType;
35+
data: any;
36+
}[] => {
2937
const contentType = plain.recordLayerHeader.contentType;
3038

3139
switch (contentType) {
3240
case ContentType.changeCipherSpec: {
3341
log(dtls.sessionId, "change cipher spec");
34-
return {
35-
type: ContentType.changeCipherSpec,
36-
data: undefined,
37-
};
42+
return [
43+
{
44+
type: ContentType.changeCipherSpec,
45+
data: undefined,
46+
},
47+
];
3848
}
3949
case ContentType.handshake: {
4050
let raw = plain.fragment;
@@ -48,20 +58,29 @@ export const parsePlainText =
4858
throw error;
4959
}
5060
try {
51-
return {
52-
type: ContentType.handshake,
53-
data: FragmentedHandshake.deSerialize(raw),
54-
};
61+
let start = 0;
62+
const handshakes: { type: ContentType; data: any }[] = [];
63+
while (raw.length > start) {
64+
const handshake = FragmentedHandshake.deSerialize(
65+
raw.subarray(start),
66+
);
67+
handshakes.push({ type: ContentType.handshake, data: handshake });
68+
start += handshake.fragment_length + 12;
69+
}
70+
71+
return handshakes;
5572
} catch (error) {
5673
err(dtls.sessionId, "decSerialize failed", error, raw);
5774
throw error;
5875
}
5976
}
6077
case ContentType.applicationData: {
61-
return {
62-
type: ContentType.applicationData,
63-
data: cipher.decryptPacket(plain),
64-
};
78+
return [
79+
{
80+
type: ContentType.applicationData,
81+
data: cipher.decryptPacket(plain),
82+
},
83+
];
6584
}
6685
case ContentType.alert: {
6786
let alert = Alert.deSerialize(plain.fragment);
@@ -84,10 +103,10 @@ export const parsePlainText =
84103
if (alert.level > 1) {
85104
throw new Error("alert fatal error");
86105
}
87-
return { type: ContentType.alert, data: undefined };
106+
return [{ type: ContentType.alert, data: undefined }];
88107
}
89108
default: {
90-
return { type: ContentType.alert, data: undefined };
109+
return [{ type: ContentType.alert, data: undefined }];
91110
}
92111
}
93112
};

packages/dtls/src/socket.ts

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,39 +81,41 @@ export class DtlsSocket {
8181

8282
for (const packet of packets) {
8383
try {
84-
const message = parsePlainText(this.dtls, this.cipher)(packet);
85-
switch (message.type) {
86-
case ContentType.handshake:
87-
{
88-
const handshake = message.data as FragmentedHandshake;
89-
const handshakes = this.handleFragmentHandshake([handshake]);
90-
const assembled = Object.values(
91-
handshakes.reduce(
92-
(acc: { [type: string]: FragmentedHandshake[] }, cur) => {
93-
if (!acc[cur.msg_type]) acc[cur.msg_type] = [];
94-
acc[cur.msg_type].push(cur);
95-
return acc;
96-
},
97-
{},
98-
),
99-
)
100-
.map((v) => FragmentedHandshake.assemble(v))
101-
.sort((a, b) => a.msg_type - b.msg_type);
84+
const messages = parsePlainText(this.dtls, this.cipher)(packet);
85+
for (const message of messages) {
86+
switch (message.type) {
87+
case ContentType.handshake:
88+
{
89+
const handshake = message.data as FragmentedHandshake;
90+
const handshakes = this.handleFragmentHandshake([handshake]);
91+
const assembled = Object.values(
92+
handshakes.reduce(
93+
(acc: { [type: string]: FragmentedHandshake[] }, cur) => {
94+
if (!acc[cur.msg_type]) acc[cur.msg_type] = [];
95+
acc[cur.msg_type].push(cur);
96+
return acc;
97+
},
98+
{},
99+
),
100+
)
101+
.map((v) => FragmentedHandshake.assemble(v))
102+
.sort((a, b) => a.msg_type - b.msg_type);
102103

103-
this.onHandleHandshakes(assembled).catch((error) => {
104-
err(this.dtls.sessionId, "onHandleHandshakes error", error);
105-
this.onError.execute(error);
106-
});
107-
}
108-
break;
109-
case ContentType.applicationData:
110-
{
111-
this.onData.execute(message.data as Buffer);
112-
}
113-
break;
114-
case ContentType.alert:
115-
this.onClose.execute();
116-
break;
104+
this.onHandleHandshakes(assembled).catch((error) => {
105+
err(this.dtls.sessionId, "onHandleHandshakes error", error);
106+
this.onError.execute(error);
107+
});
108+
}
109+
break;
110+
case ContentType.applicationData:
111+
{
112+
this.onData.execute(message.data as Buffer);
113+
}
114+
break;
115+
case ContentType.alert:
116+
this.onClose.execute();
117+
break;
118+
}
117119
}
118120
} catch (error) {
119121
err(this.dtls.sessionId, "catch udpOnMessage error", error);

0 commit comments

Comments
 (0)