This commit is contained in:
地平线
2015-09-11 17:54:49 +08:00
parent 344de75c95
commit 1e6f293ca4
8 changed files with 133 additions and 174 deletions

View File

@@ -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);

View File

@@ -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() {

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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;
}