diff --git a/src/com/wentch/redkale/net/icep/BindingIcepServlet.java b/src/com/wentch/redkale/net/icep/BindingIcepServlet.java index 84f21d3ab..fa588b1ef 100644 --- a/src/com/wentch/redkale/net/icep/BindingIcepServlet.java +++ b/src/com/wentch/redkale/net/icep/BindingIcepServlet.java @@ -23,7 +23,8 @@ public class BindingIcepServlet extends IcepServlet { StunPacket packet = request.getStunPacket(); ByteBuffer buffer = response.getContext().pollBuffer(); packet.addAttribute(new XorMappedAddressAttribute(request.getRemoteAddress())); - packet.getHeader().setRequestid((short) (StunHeader.TYPE_SUCCESS | StunHeader.ACTION_BINDING)); + packet.addAttribute(new MappedAddressAttribute(request.getRemoteAddress())); + packet.getHeader().setRequestid((StunHeader.TYPE_SUCCESS | StunHeader.ACTION_BINDING)); packet.encode(buffer); buffer.flip(); Utility.println("响应结果: ", buffer); diff --git a/src/com/wentch/redkale/net/icep/IcepRequest.java b/src/com/wentch/redkale/net/icep/IcepRequest.java index 0741afb23..aab8ecf04 100644 --- a/src/com/wentch/redkale/net/icep/IcepRequest.java +++ b/src/com/wentch/redkale/net/icep/IcepRequest.java @@ -31,18 +31,14 @@ public class IcepRequest extends Request { Utility.println(Utility.now() + "-------" + getRemoteAddress() + " ", buffer); if (buffer.remaining() < 20) return -1; this.requestid = buffer.getShort(); - short typeid = (short) ((this.requestid >> 16) & 0xffff); + short typeid = (short) ((this.requestid >> 8) & 0xffff); short actionid = (short) (this.requestid & 0xffff); + int bodysize = buffer.getShort() & 0xffff; byte[] bytes = new byte[16]; buffer.get(bytes); StunHeader header = new StunHeader(typeid, actionid, bytes); this.stunPacket = new StunPacket(header); - return -1; - } - - public static void main(String[] args) throws Exception { - int a = 0xabcd0000; - System.out.println(Integer.toHexString((a >> 16) & 0xffff)); + return 0; } public InetSocketAddress getRemoteAddress() { diff --git a/src/com/wentch/redkale/net/icep/attr/MappedAddressAttribute.java b/src/com/wentch/redkale/net/icep/attr/MappedAddressAttribute.java new file mode 100644 index 000000000..fd5ae68ff --- /dev/null +++ b/src/com/wentch/redkale/net/icep/attr/MappedAddressAttribute.java @@ -0,0 +1,112 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.wentch.redkale.net.icep.attr; + +import com.wentch.redkale.net.icep.*; +import com.wentch.redkale.net.icep.stun.*; +import com.wentch.redkale.util.*; +import java.net.*; +import java.nio.*; + +/** + * + * @author zhangjx + */ +public class MappedAddressAttribute extends StunAttribute { + + protected InetSocketAddress address; + + public MappedAddressAttribute() { + } + + public MappedAddressAttribute(InetSocketAddress address) { + this.address = address; + } + + /** + 0000 b8 2a 72 c8 7c 7e 08 57 00 60 3b f6 08 00 45 00 .*r.|~.W.`;...E. + 0010 00 78 00 00 40 00 30 11 6f 1a d8 5d f6 12 0a 1c .x..@.0.o..].... + 0020 02 cf 0d 96 e2 ba 00 64 f0 b3 + 01 01 00 48 21 12 a4 42 50 38 69 55 2b 65 78 66 4e 68 76 32 00 01 .BP8iU+exfNhv2.. + 0040 00 08 00 01 e2 ba 71 5c fb ed 00 04 00 08 00 01 ......q\........ + 0050 0d 96 d8 5d f6 12 00 05 00 08 00 01 0d 97 d8 5d ...]...........] + 0060 f6 0f 80 20 00 08 00 01 c3 a8 50 4e 5f af 80 22 ... ......PN_.." + 0070 00 14 56 6f 76 69 64 61 2e 6f 72 67 20 30 2e 39 ..Vovida.org 0.9 + 0080 37 2d 43 50 43 00 7-CPC. + @param args + @throws Exception + */ + public static void main(String[] args) throws Exception { + final byte[] transactionid = format("21 12 a4 42 50 38 69 55 2b 65 78 66 4e 68 76 32"); + byte[] attrs = format("80 20 00 08 00 01 c3 a8 50 4e 5f af"); + XorMappedAddressAttribute attr = new XorMappedAddressAttribute().decode(ByteBuffer.wrap(attrs), transactionid); + System.out.println(attr); + ByteBuffer buffer = ByteBuffer.allocate(1024); + attr.encode(buffer, transactionid); + buffer.flip(); + Utility.println(null, buffer); + } + + protected static byte[] format(String string) { + String[] strs = string.split("\\s+"); + byte[] bs = new byte[strs.length]; + for (int i = 0; i < bs.length; i++) { + bs[i] = (byte) Integer.parseInt(strs[i], 16); + } + return bs; + } + + @Override + public MappedAddressAttribute decode(final ByteBuffer buffer, final byte[] transactionid) { + final short attrid = (short) (buffer.getShort() & 0x00ff); + if (attrid != getAttributeid()) throw new IcepException(this.getClass().getSimpleName() + " has illegal attributeid " + attrid); + final int bodysize = buffer.getShort() & 0xffff; + final short family = buffer.getShort(); + if (family == 0x0001 && bodysize != 8) throw new IcepException("family = " + family + " but bodysize = " + bodysize); + if (family == 0x0002 && bodysize != 20) throw new IcepException("family = " + family + " but bodysize = " + bodysize); + final int port = buffer.getShort() & 0xffff; + byte[] bytes = new byte[family == 0x0002 ? 16 : 4]; + buffer.get(bytes); + try { + this.address = new InetSocketAddress(InetAddress.getByAddress(bytes), port); + } catch (UnknownHostException e) { + throw new IcepException("port = " + port + " and address = " + Utility.binToHexString(bytes), e); + } + return this; + } + + @Override + public ByteBuffer encode(final ByteBuffer buffer, final byte[] transactionid) { + final boolean ipv6 = this.address.getAddress() instanceof Inet6Address; + buffer.putShort((short) getAttributeid()); + buffer.putShort((short) (ipv6 ? 20 : 8)); + buffer.putShort((short) (ipv6 ? 0x0002 : 0x0001)); + buffer.putShort((short) this.address.getPort()); + final byte[] bytes = this.address.getAddress().getAddress(); + buffer.put(bytes); + return buffer; + } + + @Override + public short getAttributeid() { + return 0x0001; + } + + @Override + public String getName() { + return "MAPPED-ADDRESS"; + } + + public InetSocketAddress getInetSocketAddress() { + return address; + } + + @Override + public String toString() { + return getName() + ":" + address; + } + +} diff --git a/src/com/wentch/redkale/net/icep/attr/XorMappedAddressAttribute.java b/src/com/wentch/redkale/net/icep/attr/XorMappedAddressAttribute.java index 6613ce118..947c03819 100644 --- a/src/com/wentch/redkale/net/icep/attr/XorMappedAddressAttribute.java +++ b/src/com/wentch/redkale/net/icep/attr/XorMappedAddressAttribute.java @@ -6,7 +6,6 @@ package com.wentch.redkale.net.icep.attr; import com.wentch.redkale.net.icep.*; -import com.wentch.redkale.net.icep.stun.*; import com.wentch.redkale.util.*; import java.net.*; import java.nio.*; @@ -15,15 +14,13 @@ import java.nio.*; * * @author zhangjx */ -public class XorMappedAddressAttribute extends StunAttribute { - - private InetSocketAddress address; +public class XorMappedAddressAttribute extends MappedAddressAttribute { public XorMappedAddressAttribute() { } public XorMappedAddressAttribute(InetSocketAddress address) { - this.address = address; + super(address); } /** @@ -50,15 +47,6 @@ public class XorMappedAddressAttribute extends StunAttribute { Utility.println(null, buffer); } - private static byte[] format(String string) { - String[] strs = string.split("\\s+"); - byte[] bs = new byte[strs.length]; - for (int i = 0; i < bs.length; i++) { - bs[i] = (byte) Integer.parseInt(strs[i], 16); - } - return bs; - } - @Override public XorMappedAddressAttribute decode(final ByteBuffer buffer, final byte[] transactionid) { final short attrid = (short) (buffer.getShort() & 0x00ff); @@ -106,13 +94,4 @@ public class XorMappedAddressAttribute extends StunAttribute { return "XOR-MAPPED-ADDRESS"; } - public InetSocketAddress getAddress() { - return address; - } - - @Override - public String toString() { - return getName() + ":" + address; - } - } diff --git a/src/com/wentch/redkale/net/icep/rtcp/RtcpHeader.java b/src/com/wentch/redkale/net/icep/rtcp/RtcpHeader.java deleted file mode 100644 index 2ef136087..000000000 --- a/src/com/wentch/redkale/net/icep/rtcp/RtcpHeader.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.wentch.redkale.net.icep.rtcp; - -/** - 1byte = 8bits - * - * @author zhangjx - */ -public class RtcpHeader { - - public static final int RTCP_SR = 200; //发送者报告 描述作为活跃发送者成员的发送和接收统计数字 - - public static final int RTCP_RR = 201; //接收者报告 描述非活跃发送者成员的接收统计数字 - - public static final int RTCP_SDES = 202; //源描述项。 其中包括规范名CNAME - - public static final int RTCP_BYE = 203; //关闭 表明参与者将结束会话 - - public static final int RTCP_APP = 204; //应用描述功能 - - /** - * protocol version - * 占2比特。 表示RTP 的版本号。 - */ - protected int version; - - /** - * padding flag - * 占1比特。 置“1”表示用户数据最后加有填充位,用户数据中最后一个字节是填充位计数,它表示一共加了多少个填充位。在两种情况下可能 - * 需要填充,一是某些加密算法要求数据块大小固定;二是在一个低层协议数据包中装载多个RTP 分组。 - */ - protected boolean padding; // - - /** - * 占1比特。 置“1”表示RTP 报头后紧随一个扩展报头。 - */ - protected boolean extend; - - /** - * varies by packet type - */ - protected int count; - - /** - * RTCP packet type - */ - protected int packetType; //占1个字节 - - /** - * Packet length in words, w/o this word - */ - protected int length; - - protected RtcpHeader() { - this(false, 0); - } - - public RtcpHeader(boolean padding, int pt) { - this.padding = padding; - this.packetType = pt; - this.count = 0; - this.length = 0; - this.version = 2; - } - - protected int decode(byte[] rawData, int offSet) { - int b = rawData[offSet++] & 0xff; - - this.version = (b & 0xC0) >> 6; - this.padding = (b & 0x20) == 0x020; - - this.count = b & 0x1F; - - this.packetType = rawData[offSet++] & 0x000000FF; - - this.length |= rawData[offSet++] & 0xFF; - this.length <<= 8; - this.length |= rawData[offSet++] & 0xFF; - - /** - * The length of this RTCP packet in 32-bit words minus one, including - * the header and any padding. (The offset of one makes zero a valid - * length and avoids a possible infinite loop in scanning a compound - * RTCP packet, while counting 32-bit words avoids a validity check for - * a multiple of 4.) - */ - this.length = (this.length * 4) + 4; - - return offSet; - } - - protected int encode(byte[] rawData, int offSet) { - rawData[offSet] = (byte) (this.version << 6); - if (this.padding) { - rawData[offSet] = (byte) (rawData[offSet] | 0x20); - } - - rawData[offSet] = (byte) (rawData[offSet] | (this.count & 0x1F)); - - offSet++; - - rawData[offSet++] = (byte) (this.packetType & 0x000000FF); - - // Setting length is onus of concrete class. But we increment the offSet - offSet += 2; - - return offSet; - } - - public int getVersion() { - return version; - } - - public boolean isPadding() { - return padding; - } - - public int getCount() { - return count; - } - - public int getPacketType() { - return packetType; - } - - public int getLength() { - return length; - } -} diff --git a/src/com/wentch/redkale/net/icep/rtp/RtpHeader.java b/src/com/wentch/redkale/net/icep/rtp/RtpHeader.java index 081b27e9b..134d112ef 100644 --- a/src/com/wentch/redkale/net/icep/rtp/RtpHeader.java +++ b/src/com/wentch/redkale/net/icep/rtp/RtpHeader.java @@ -116,8 +116,12 @@ public class RtpHeader implements IcepCoder { return buffer; } + public static int getSsrc(final ByteBuffer buffer) { + return buffer.getInt(8); + } + public int getVersion() { - return (headval << 30) & 0b11; + return (headval >> 30) & 0b11; } public boolean isPadding() { @@ -173,7 +177,7 @@ public class RtpHeader implements IcepCoder { } public int getCrscs() { - return (headval >> 4 << 28) & 0b1111; + return (headval >> 24) & 0b1111; } public boolean isMarker() { @@ -181,7 +185,7 @@ public class RtpHeader implements IcepCoder { } public int getPayloadtype() { - return (headval >> 9 << 25) & 0b1111111; + return (headval >> 16) & 0b1111111; } public void setPayloadtype(int payloadtype) { diff --git a/src/com/wentch/redkale/net/icep/stun/StunHeader.java b/src/com/wentch/redkale/net/icep/stun/StunHeader.java index 1c62a9835..8bafdeb26 100644 --- a/src/com/wentch/redkale/net/icep/stun/StunHeader.java +++ b/src/com/wentch/redkale/net/icep/stun/StunHeader.java @@ -14,7 +14,7 @@ import java.security.*; * * @author zhangjx */ -public class StunHeader implements IcepCoder{ +public class StunHeader implements IcepCoder { public static final int MAGIC_COOKIE = 0x2112A442; @@ -73,6 +73,7 @@ public class StunHeader implements IcepCoder{ this.transactionid = transactionid0 == null ? generateTransactionid() : transactionid0; } + @Override public StunHeader decode(final ByteBuffer buffer) { short requestid = buffer.getShort(); this.typeid = (short) (requestid << 2); @@ -83,10 +84,11 @@ public class StunHeader implements IcepCoder{ return this; } + @Override public ByteBuffer encode(final ByteBuffer buffer) { buffer.put((byte) this.typeid); buffer.put((byte) this.actionid); - buffer.putShort((short) 0); //bodysize + buffer.putShort((short) this.bodysize); //bodysize buffer.put(transactionid); return buffer; } @@ -105,8 +107,8 @@ public class StunHeader implements IcepCoder{ return "0x" + str; } - public void setRequestid(short requestid) { - this.typeid = (short) (requestid << 2); + public void setRequestid(int requestid) { + this.typeid = (short) (requestid >> 8); this.actionid = (short) (requestid & 0xff); } diff --git a/src/com/wentch/redkale/net/icep/stun/StunPacket.java b/src/com/wentch/redkale/net/icep/stun/StunPacket.java index 96436d5a8..3499c938b 100644 --- a/src/com/wentch/redkale/net/icep/stun/StunPacket.java +++ b/src/com/wentch/redkale/net/icep/stun/StunPacket.java @@ -30,9 +30,7 @@ public class StunPacket { attr.encode(buffer, transactionid); } int end = buffer.position(); - buffer.position(start + 2); - buffer.putShort((short) (end - start - 20)); - buffer.position(end); + buffer.putShort(start + 2, (short) (end - start - 20)); return buffer; }