This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
112
src/com/wentch/redkale/net/icep/attr/MappedAddressAttribute.java
Normal file
112
src/com/wentch/redkale/net/icep/attr/MappedAddressAttribute.java
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -116,8 +116,12 @@ public class RtpHeader implements IcepCoder<RtpHeader> {
|
||||
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<RtpHeader> {
|
||||
}
|
||||
|
||||
public int getCrscs() {
|
||||
return (headval >> 4 << 28) & 0b1111;
|
||||
return (headval >> 24) & 0b1111;
|
||||
}
|
||||
|
||||
public boolean isMarker() {
|
||||
@@ -181,7 +185,7 @@ public class RtpHeader implements IcepCoder<RtpHeader> {
|
||||
}
|
||||
|
||||
public int getPayloadtype() {
|
||||
return (headval >> 9 << 25) & 0b1111111;
|
||||
return (headval >> 16) & 0b1111111;
|
||||
}
|
||||
|
||||
public void setPayloadtype(int payloadtype) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.security.*;
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public class StunHeader implements IcepCoder<StunHeader>{
|
||||
public class StunHeader implements IcepCoder<StunHeader> {
|
||||
|
||||
public static final int MAGIC_COOKIE = 0x2112A442;
|
||||
|
||||
@@ -73,6 +73,7 @@ public class StunHeader implements IcepCoder<StunHeader>{
|
||||
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<StunHeader>{
|
||||
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<StunHeader>{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user