Skip to content

Our customized serialization id exceeds the maximum limit, now it cannot work on 2.6.2 anymore. #1903

Closed
@linzhiqiang0514

Description

@linzhiqiang0514

前提:
我们自定义了序列化方式,serialization.getContentTypeId() == 88
超出计算的最大值。
按照ExchangeCodec的逻辑,这个值最大允许32。
88在服务端经过计算,变成24,无法获取到序列化方式。

在2.6.0版本时,获取序列化方式,采用兼容处理
CodecSupport.java代码如下:

public static Serialization getSerialization(URL url) {
        return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(
                url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));
    }

    public static Serialization getSerialization(URL url, Byte id) {
        Serialization result = getSerializationById(id);
        if (result == null) {
            result = getSerialization(url);
        }
        return result;
    }

上述代码会从SPI接口,根据url获取的参数,进一步获取。

在2.6.2版本时,获取序列化方式更改,根据id获取不到则抛出异常

public static Serialization getSerialization(URL url, Byte id) throws IOException {
        Serialization serialization = getSerializationById(id);
        String serializationName = url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION);
        // Check if "serialization id" passed from network matches the id on this side(only take effect for JDK serialization), for security purpose.
        if (serialization == null
                || ((id == 3 || id == 7 || id == 4) && !(serializationName.equals(ID_SERIALIZATIONNAME_MAP.get(id))))) {
            throw new IOException("Unexpected serialization id:" + id + " received from network, please check if the peer send the right id.");
        }
        return serialization;
    }

异常抛出后,没有做处理,导致的服务端hang住不返回,需要等待超时报错。代码在如下位置:
com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(Channel, ChannelBuffer, int, byte[]) Line:124

try {
            return decodeBody(channel, is, header);
        } finally {
            if (is.available() > 0) {
                try {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Skip input stream " + is.available());
                    }
                    StreamUtils.skipUnusedStream(is);
                } catch (IOException e) {
                    logger.warn(e.getMessage(), e);
                }
            }
        }
    }

    protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {
        byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);
        Serialization s = CodecSupport.getSerialization(channel.getUrl(), proto);
        ObjectInput in = s.deserialize(channel.getUrl(), is);

Line:141 抛出异常.
Line:124 不做处理。

导致服务不返回。

Metadata

Metadata

Labels

type/bugBugs to being fixed

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions