关于苹果推送的问题

最近写程序给苹果推送服务器APNS发消息。具体方式在它的官网上说的很清楚。在开发过程中遇到一个问题,这个问题和APNS的反馈机制有关。流程是这样的:创建一个连接APNS服务器的tcp连接,然后将一定格式的多条消息打包发给APNS,如果这些没有什么错误的话,APNS是没有反馈的。(这不像给WNS,WNS给每个http格式封装的消息都有个应答,告知成功与否)。如果APNS发现某个消息出现错误(比如Token非法),它就会反馈一个6字节的数据,其中包含那个错误消息的ID,然后close套接字。如下图所示:

关于苹果推送的问题_第1张图片

我的做法:

1)客户端将很多消息放到一个包里,然后调用SSL_write发送数据。

2)写了一个模拟APNS来接收,并且模拟发送bad id, close过程。

当client端正在write的时候,APNS收到一个非法的消息,于是它将这个消息ID发送给client,然后close套接字。注意,此时client端还在write里面,因为缓冲区里还有数据在发,这样会造成APNS发送一个RST分节。因为APNS已经关闭,client还在给它发数据,由此引发APNS发送RST。这时候,问题出现了,client端从write返回后,发现套接字可读,它知道一定是APNS发回了错误的MsgID,于是client去SSL_read(),但是,SSL_read返回connection reset by peer错误,因为client端的套接字之前已经收到了一个RST,套接字会丢弃缓冲区的所有数据,返回错误的。最终结果就是我们丢失了那个错误的MsgID,我们无法知道从哪里需要重发了。

目前,没找到好办法解决。找找资料,好好想想。


2013-7-3

昨天下午请教了一个高手,他说APNS可能在反馈回6字节的数据后,不会强制close掉套接字,有可能用shutdown,等客户端读到反馈数据再关闭。按理说APNS是应该等客户端读完它的反馈数据后再close的。但是这样会出现问题,如果客户端程序读出反馈后,并不close套接字,那么APNS怎么知道客户端有没有读出来,有可能APNS一直保持着这个连接。可能这就给攻击者提供了机会了。有可能APNS为了安全考虑,反馈后直接close套接字。

我今天做了个验:直接连APNS服务器,SSL_write一个1M的缓冲区数据,其中第一条消息就非法,于是我发现SSL_write自己就返回了错误connection reset by peer。这样我们就不能读回那个错误的MsgID了。

这个试验结果说明:苹果APNS在收到一个非法消息后,反馈一个6字节信息,然后直接就close掉了。这样会造成:有时候客户端无法读回那个6字节的反馈(由于收到了RST);但是有时候是能读到那6个字节的反馈(没有收到RST)。

你可能感兴趣的:(关于苹果推送的问题)