$Id: 016_ICE_subprotocol_reply_fix.diff 1044 2004-02-16 17:40:33Z branden $ This patch by Jochen Voss. DESCRIPTION OF THE PROBLEM: When two hosts communicate over an ICE connection and use different major opcodes for a subprotocol, it is impossible to use message replies. Let HOST-A and HOST-B be two hosts which communicate over an ICE connection and use a subprotocol PROT. Both have obtained an opcode for PROT, HOST-A got the opcode 1 from `IceRegisterForProtocolSetup' and HOST-B got the opcode 2 from `IceRegisterForProtocolReply' (he uses several protocols simultaneously, so the value is not 1). Now HOST-A sents a message wich requires a reply. In order to do so he sets up an `IceReplyWaitInfo' and calls `IceProcessMessages': IceReplyWaitInfo reply_info; Bool reply_ready; reply_info.sequence_of_request = IceLastSentSequenceNumber (ice_conn); reply_info.major_opcode_of_request = opcode; reply_info.minor_opcode_of_request = PROT_Question; reply_info.reply = reply; do { IceProcessMessagesStatus process_status; process_status = IceProcessMessages (ice_conn, &reply_info, &reply_ready); ... } while (! reply_ready); The `reply_info.major_opcode_of_request' field contains the value 1, now. Next, HOST-B's reply arrives while HOST-A is executing the function `IceProcessMessages'. Within this function, the `reply_wait' is registered via the command _IceAddReplyWait (iceConn, replyWait); This makes ICE wait for something with major opcode 1. But the variable `header' has `header->majorOpcode == 2', because HOST-B sent it this way. So the following call useThisReplyWait = _IceSearchReplyWaits (iceConn, header->majorOpcode); (also from `IceProcessMessages') does not find my `reply_wait' because ICE searchs for the major opcode 2, not 1! I think this is a bug in the ICE library. Not submitted upstream yet. --- xc/lib/ICE/process.c~ 2003-01-01 17:27:29.000000000 -0500 +++ xc/lib/ICE/process.c 2003-01-01 17:32:09.000000000 -0500 @@ -247,16 +247,33 @@ _IceAddReplyWait (iceConn, replyWait); - /* * Note that there are two different replyWaits. The first is * the one passed into IceProcessMessages, and is the replyWait * for the message the client is blocking on. The second is * the replyWait for the message currently being processed * by IceProcessMessages. We call it "useThisReplyWait". + * + * Also, when two hosts communicate over an ICE connection and use + * different major opcodes for a subprotocol, it is impossible + * to use message replies unless we translate opcodes before + * comparing them. */ + + { + int op; - useThisReplyWait = _IceSearchReplyWaits (iceConn, header->majorOpcode); + if (header->majorOpcode == 0) + { + op = 0; + } + else + { + int idx = header->majorOpcode - iceConn->his_min_opcode; + op = iceConn->process_msg_info[idx].my_opcode; + } + useThisReplyWait = _IceSearchReplyWaits (iceConn, op); + } } if (header->majorOpcode == 0)