/// <summary>Send back an ONC/RPC reply to the caller who sent in this call.</summary> /// <remarks> /// Send back an ONC/RPC reply to the caller who sent in this call. This /// automatically sends an ONC/RPC reply header before the reply part, /// indicating success within the header. /// </remarks> /// <param name="reply">Reply body the ONC/RPC reply message.</param> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully serialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> public virtual void reply(org.acplt.oncrpc.XdrAble rply) { reply(new org.acplt.oncrpc.server.OncRpcServerReplyMessage(callMessage, org.acplt.oncrpc.OncRpcReplyStatus .ONCRPC_MSG_ACCEPTED, org.acplt.oncrpc.OncRpcAcceptStatus.ONCRPC_SUCCESS, org.acplt.oncrpc.OncRpcReplyMessage .UNUSED_PARAMETER, org.acplt.oncrpc.OncRpcReplyMessage.UNUSED_PARAMETER, org.acplt.oncrpc.OncRpcReplyMessage .UNUSED_PARAMETER, org.acplt.oncrpc.OncRpcReplyMessage.UNUSED_PARAMETER), rply); }
/// <summary> /// Creates a new <code>KscPackageUpdateEvent</code> object and /// initializes its state. /// </summary> /// <remarks> /// Creates a new <code>KscPackageUpdateEvent</code> object and /// initializes its state. /// </remarks> /// <param name="source"> /// The /// <see cref="OncRpcUdpClient">ONC/RPC client object</see> /// which has /// fired this event. /// </param> /// <param name="replyAddress">Internetaddress of reply's origin.</param> /// <param name="procedureNumber">Procedure number of ONC/RPC call.</param> /// <param name="params">The ONC/RPC call resulting in this reply.</param> /// <param name="reply">The ONC/RPC reply itself.</param> public OncRpcBroadcastEvent(org.acplt.oncrpc.OncRpcUdpClient source, IPAddress replyAddress, int procedureNumber, org.acplt.oncrpc.XdrAble @params, org.acplt.oncrpc.XdrAble reply) { this.replyAddress = replyAddress; this.procedureNumber = procedureNumber; this.@params = @params; this.reply = reply; }
/// <summary>Retrieves the parameters sent within an ONC/RPC call message.</summary> /// <remarks> /// Retrieves the parameters sent within an ONC/RPC call message. It also /// makes sure that the deserialization process is properly finished after /// the call parameters have been retrieved. Under the hood this method /// therefore calls /// <see cref="org.acplt.oncrpc.XdrDecodingStream.endDecoding()">org.acplt.oncrpc.XdrDecodingStream.endDecoding() /// </see> /// to free any /// pending resources from the decoding stage. /// </remarks> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully deserialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> internal override void retrieveCall(org.acplt.oncrpc.XdrAble call) { call.xdrDecode(receivingXdr); if (pendingDecoding) { pendingDecoding = false; receivingXdr.endDecoding(); } }
// for ( refreshesLeft ) /// <summary>Issues a batched call for a remote procedure to an ONC/RPC server.</summary> /// <remarks> /// Issues a batched call for a remote procedure to an ONC/RPC server. /// Below is a small example (exception handling ommited for clarity): /// <pre> /// OncRpcTcpClient client = new OncRpcTcpClient( /// InetAddress.getByName("localhost"), /// myprogramnumber, myprogramversion, /// OncRpcProtocols.ONCRPC_TCP); /// client.callBatch(42, myparams, false); /// client.callBatch(42, myotherparams, false); /// client.callBatch(42, myfinalparams, true); /// </pre> /// In the example above, three calls are batched in a row and only be sent /// all together with the third call. Note that batched calls must not expect /// replies, with the only exception being the last call in a batch: /// <pre> /// client.callBatch(42, myparams, false); /// client.callBatch(42, myotherparams, false); /// client.call(43, myfinalparams, myfinalresult); /// </pre> /// </remarks> /// <param name="procedureNumber">Procedure number of the procedure to call.</param> /// <param name="params"> /// The parameters of the procedure to call, contained /// in an object which implements the /// <see cref="XdrAble">XdrAble</see> /// interface. /// </param> /// <param name="flush"> /// Make sure that all pending batched calls are sent to /// the server. /// </param> /// <exception cref="OncRpcException">if an ONC/RPC error occurs.</exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> public virtual void batchCall(int procedureNumber, org.acplt.oncrpc.XdrAble @params , bool flush) { lock (this) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to send all its data // to the server. We don't then need to wait for an answer. And // we don't need to take care of credential refreshes either. // nextXid(); org.acplt.oncrpc.OncRpcClientCallMessage callHeader = new org.acplt.oncrpc.OncRpcClientCallMessage (xid, program, version, procedureNumber, auth); // // Send call message to server. If we receive an IOException, // then we'll throw the appropriate ONC/RPC (client) exception. // Note that we use a connected stream, so we don't need to // specify a destination when beginning serialization. // try { socket.SendTimeout = transmissionTimeout; sendingXdr.beginEncoding(null, 0); callHeader.xdrEncode(sendingXdr); @params.xdrEncode(sendingXdr); sendingXdr.endEncoding(flush); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTSEND , e.Message)); } } }
/// <summary>Calls a remote procedure on an ONC/RPC server.</summary> /// <remarks> /// Calls a remote procedure on an ONC/RPC server. /// <p>Please note that while this method supports call batching by /// setting the communication timeout to zero /// (<code>setTimeout(0)</code>) you should better use /// <see cref="batchCall(int, XdrAble, bool)">batchCall(int, XdrAble, bool)</see> /// as it provides better control over when the /// batch should be flushed to the server. /// </remarks> /// <param name="procedureNumber">Procedure number of the procedure to call.</param> /// <param name="versionNumber">Protocol version number.</param> /// <param name="params"> /// The parameters of the procedure to call, contained /// in an object which implements the /// <see cref="XdrAble">XdrAble</see> /// interface. /// </param> /// <param name="result">The object receiving the result of the procedure call.</param> /// <exception cref="OncRpcException">if an ONC/RPC error occurs.</exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> public override void call(int procedureNumber, int versionNumber, org.acplt.oncrpc.XdrAble @params, org.acplt.oncrpc.XdrAble result) { lock (this) { // Refresh: for (int refreshesLeft = 1; refreshesLeft >= 0; --refreshesLeft) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to send all its data // to the server. Then wait for an answer, receive it and decode // it. So that's the bottom line of what we do right here. // nextXid(); org.acplt.oncrpc.OncRpcClientCallMessage callHeader = new org.acplt.oncrpc.OncRpcClientCallMessage (xid, program, versionNumber, procedureNumber, auth); org.acplt.oncrpc.OncRpcClientReplyMessage replyHeader = new org.acplt.oncrpc.OncRpcClientReplyMessage (auth); // // Send call message to server. If we receive an IOException, // then we'll throw the appropriate ONC/RPC (client) exception. // Note that we use a connected stream, so we don't need to // specify a destination when beginning serialization. // try { socket.ReceiveTimeout = transmissionTimeout; sendingXdr.beginEncoding(null, 0); callHeader.xdrEncode(sendingXdr); @params.xdrEncode(sendingXdr); if (timeout != 0) { sendingXdr.endEncoding(); } else { sendingXdr.endEncoding(false); } } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTSEND , e.Message)); } // // Receive reply message from server -- at least try to do so... // In case of batched calls we don't need no stinkin' answer, so // we can do other, more interesting things. // if (timeout == 0) { return; } try { // // Keep receiving until we get the matching reply. // while (true) { socket.ReceiveTimeout = timeout; receivingXdr.beginDecoding(); socket.ReceiveTimeout = transmissionTimeout; // // First, pull off the reply message header of the // XDR stream. In case we also received a verifier // from the server and this verifier was invalid, broken // or tampered with, we will get an // OncRpcAuthenticationException right here, which will // propagate up to the caller. If the server reported // an authentication problem itself, then this will // be handled as any other rejected ONC/RPC call. // try { replyHeader.xdrDecode(receivingXdr); } catch (org.acplt.oncrpc.OncRpcException e) { // // ** SF bug #1262106 ** // // We ran into some sort of trouble. Usually this will have // been a buffer underflow. Whatever, end the decoding process // and ensure this way that the next call has a chance to start // from a clean state. // receivingXdr.endDecoding(); throw (e); } // // Only deserialize the result, if the reply matches the // call. Otherwise skip this record. // if (replyHeader.messageId == callHeader.messageId) { break; } receivingXdr.endDecoding(); } // // Make sure that the call was accepted. In case of unsuccessful // calls, throw an exception, if it's not an authentication // exception. In that case try to refresh the credential first. // if (!replyHeader.successfullyAccepted()) { receivingXdr.endDecoding(); // // Check whether there was an authentication // problem. In this case first try to refresh the // credentials. // if ((refreshesLeft > 0) && (replyHeader.replyStatus == org.acplt.oncrpc.OncRpcReplyStatus .ONCRPC_MSG_DENIED) && (replyHeader.rejectStatus == org.acplt.oncrpc.OncRpcRejectStatus .ONCRPC_AUTH_ERROR) && (auth != null) && auth.canRefreshCred()) { // continue Refresh; continue; } // // Nope. No chance. This gets tough. // throw (replyHeader.newException()); } try { result.xdrDecode(receivingXdr); } catch (org.acplt.oncrpc.OncRpcException e) { // // ** SF bug #1262106 ** // // We ran into some sort of trouble. Usually this will have // been a buffer underflow. Whatever, end the decoding process // and ensure this way that the next call has a chance to start // from a clean state. // receivingXdr.endDecoding(); throw (e); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); return; } catch (System.IO.IOException e) { // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } } } }
// for ( refreshesLeft ) /// <summary>Broadcast a remote procedure call to several ONC/RPC servers.</summary> /// <remarks> /// Broadcast a remote procedure call to several ONC/RPC servers. For this /// you'll need to specify either a multicast address or the subnet's /// broadcast address when creating a <code>OncRpcUdpClient</code>. For /// every reply received, an event containing the reply is sent to the /// OncRpcBroadcastListener <code>listener</code>, which is the last /// parameter to the this method. /// <p>In contrast to the /// <see cref="OncRpcClient.call(int, XdrAble, XdrAble)">OncRpcClient.call(int, XdrAble, XdrAble) /// </see> /// method, /// <code>broadcastCall</code> will only send the ONC/RPC call once. It /// will then wait for answers until the timeout as set by /// <see cref="OncRpcClient.setTimeout(int)">OncRpcClient.setTimeout(int)</see> /// expires without resending the reply. /// <p>Note that you might experience unwanted results when using /// authentication types other than /// <see cref="OncRpcClientAuthNone">OncRpcClientAuthNone</see> /// , causing /// messed up authentication protocol handling objects. This depends on /// the type of authentication used. For <code>AUTH_UNIX</code> nothing /// bad happens as long as none of the servers replies with a shorthand /// verifier. If it does, then this shorthand will be used on all subsequent /// ONC/RPC calls, something you probably do not want at all. /// </remarks> /// <param name="procedureNumber">Procedure number of the procedure to call.</param> /// <param name="params"> /// The parameters of the procedure to call, contained /// in an object which implements the /// <see cref="XdrAble">XdrAble</see> /// interface. /// </param> /// <param name="result"> /// The object receiving the result of the procedure call. /// Note that this object is reused to deserialize all incomming replies /// one after another. /// </param> /// <param name="listener"> /// Listener which will get an /// <see cref="OncRpcBroadcastEvent">OncRpcBroadcastEvent</see> /// for every reply received. /// </param> /// <exception cref="OncRpcException">if an ONC/RPC error occurs.</exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> public virtual void broadcastCall(int procedureNumber, org.acplt.oncrpc.XdrAble @params , org.acplt.oncrpc.XdrAble result, org.acplt.oncrpc.OncRpcBroadcastListener listener ) { lock (this) { // // First, build the ONC/RPC call header. Then put the sending // stream into a known state and encode the parameters to be // sent. Finally tell the encoding stream to broadcast all its data. // Then wait for answers, receive and decode them one at a time. // nextXid(); org.acplt.oncrpc.OncRpcClientCallMessage callHeader = new org.acplt.oncrpc.OncRpcClientCallMessage (xid, program, version, procedureNumber, auth); org.acplt.oncrpc.OncRpcClientReplyMessage replyHeader = new org.acplt.oncrpc.OncRpcClientReplyMessage (auth); // // Broadcast the call. Note that we send the call only once and will // never resend it. // try { // // Send call message to server. Remember that we've already // "connected" the datagram socket, so java.net knows whom // to send the datagram packets. // sendingXdr.beginEncoding(host, port); callHeader.xdrEncode(sendingXdr); @params.xdrEncode(sendingXdr); sendingXdr.endEncoding(); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTSEND , e.Message)); } // // Now enter the great loop where sit waiting for replies to our // broadcast call to come in. In every case, we wait until the // (total) timeout expires. // DateTime stopTime = DateTime.Now + new TimeSpan(timeout); do { try { // // Calculate timeout until the total timeout is reached, so // we can try to meet the overall deadline. // TimeSpan currentTimeout = (stopTime - DateTime.Now); if (currentTimeout.Ticks < 0) { currentTimeout = new TimeSpan(0); } socket.ReceiveTimeout = currentTimeout.Seconds; // // Then wait for datagrams to arrive... // receivingXdr.beginDecoding(); replyHeader.xdrDecode(receivingXdr); // // Only deserialize the result, if the reply matches the call // and if the reply signals a successful call. In case of an // unsuccessful call (which mathes our call nevertheless) throw // an exception. // if (replyHeader.messageId == callHeader.messageId) { if (!replyHeader.successfullyAccepted()) { // // We got a notification of a rejected call. We silently // ignore such replies and continue listening for other // replies. // receivingXdr.endDecoding(); } result.xdrDecode(receivingXdr); // // Notify a potential listener of the reply. // if (listener != null) { org.acplt.oncrpc.OncRpcBroadcastEvent evt = new org.acplt.oncrpc.OncRpcBroadcastEvent (this, receivingXdr.getSenderAddress(), procedureNumber, @params, result); listener.replyReceived(evt); } // // Free pending resources of buffer and exit the call loop, // returning the reply to the caller through the result // object. // receivingXdr.endDecoding(); } else { // // This should raise no exceptions, when skipping the UDP // record. So if one is raised, we will rethrow an ONC/RPC // exception instead. // try { receivingXdr.endDecoding(); } catch (System.IO.IOException e) { throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } } } catch (SocketException) { } catch (System.IO.IOException e) { // // Note that we only catch timeouts here, but no other // exceptions. Those others will go up further until someone // catches them. If we get the timeout we know that it // could be time to leave the stage and so we fall through // to the total timeout check. // // // Argh. Trouble with the transport. Seems like we can't // receive data. Gosh. Go away! // throw (new org.acplt.oncrpc.OncRpcException(org.acplt.oncrpc.OncRpcException.RPC_CANTRECV , e.Message)); } }while (DateTime.Now < stopTime); return; } }
/// <summary>Send back an ONC/RPC reply to the caller who sent in this call.</summary> /// <remarks> /// Send back an ONC/RPC reply to the caller who sent in this call. This is /// a low-level function and typically should not be used by call /// dispatchers. Instead use the other /// <see cref="reply(org.acplt.oncrpc.XdrAble)">reply method</see> /// which just expects a serializable object to send back to the caller. /// </remarks> /// <param name="state"> /// ONC/RPC reply message header indicating success or failure /// and containing associated state information. /// </param> /// <param name="reply"> /// If not <code>null</code>, then this parameter references /// the reply to be serialized after the reply message header. /// </param> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully serialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> /// <seealso cref="org.acplt.oncrpc.OncRpcReplyMessage">org.acplt.oncrpc.OncRpcReplyMessage /// </seealso> /// <seealso cref="OncRpcDispatchable">OncRpcDispatchable</seealso> public virtual void reply(org.acplt.oncrpc.server.OncRpcServerReplyMessage state, org.acplt.oncrpc.XdrAble reply) { transport.reply(this, state, reply); }
/// <summary>Retrieves the parameters sent within an ONC/RPC call message.</summary> /// <remarks> /// Retrieves the parameters sent within an ONC/RPC call message. It also /// makes sure that the deserialization process is properly finished after /// the call parameters have been retrieved. /// </remarks> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully deserialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> public virtual void retrieveCall(org.acplt.oncrpc.XdrAble call) { transport.retrieveCall(call); }
/// <summary>Do not call.</summary> /// <remarks>Do not call.</remarks> /// <exception cref="System.Exception"> /// because this method must not be called for a listening /// server transport. /// </exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> /// <exception cref="System.IO.IOException"></exception> internal override void reply(org.acplt.oncrpc.server.OncRpcCallInformation callInfo , org.acplt.oncrpc.server.OncRpcServerReplyMessage state, org.acplt.oncrpc.XdrAble reply) { throw (new System.Exception("OncRpcTcpServerTransport.reply() is abstract " + "and can not be called." )); }
/// <summary>Do not call.</summary> /// <remarks>Do not call.</remarks> /// <exception cref="System.Exception"> /// because this method must not be called for a listening /// server transport. /// </exception> /// <exception cref="org.acplt.oncrpc.OncRpcException"></exception> /// <exception cref="System.IO.IOException"></exception> internal override void retrieveCall(org.acplt.oncrpc.XdrAble call) { throw (new System.Exception("OncRpcTcpServerTransport.retrieveCall() is abstract " + "and can not be called.")); }
/// <summary>Send back an ONC/RPC reply to the original caller.</summary> /// <remarks> /// Send back an ONC/RPC reply to the original caller. This is rather a /// low-level method, typically not used by applications. Dispatcher handling /// ONC/RPC calls have to use the /// <see cref="OncRpcCallInformation.reply(org.acplt.oncrpc.XdrAble)">OncRpcCallInformation.reply(org.acplt.oncrpc.XdrAble) /// </see> /// method instead on the /// call object supplied to the handler. /// <p>An appropriate implementation has to be provided in derived classes /// as it is dependent on the type of transport (whether UDP/IP or TCP/IP) /// used. /// </remarks> /// <param name="callInfo"> /// information about the original call, which are necessary /// to send back the reply to the appropriate caller. /// </param> /// <param name="state"> /// ONC/RPC reply message header indicating success or failure /// and containing associated state information. /// </param> /// <param name="reply"> /// If not <code>null</code>, then this parameter references /// the reply to be serialized after the reply message header. /// </param> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully serialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> /// <seealso cref="OncRpcCallInformation">OncRpcCallInformation</seealso> /// <seealso cref="OncRpcDispatchable">OncRpcDispatchable</seealso> internal abstract void reply(org.acplt.oncrpc.server.OncRpcCallInformation callInfo , org.acplt.oncrpc.server.OncRpcServerReplyMessage state, org.acplt.oncrpc.XdrAble reply);
/// <summary>Retrieves the parameters sent within an ONC/RPC call message.</summary> /// <remarks> /// Retrieves the parameters sent within an ONC/RPC call message. It also /// makes sure that the deserialization process is properly finished after /// the call parameters have been retrieved. Under the hood this method /// therefore calls /// <see cref="org.acplt.oncrpc.XdrDecodingStream.endDecoding()">org.acplt.oncrpc.XdrDecodingStream.endDecoding() /// </see> /// to free any /// pending resources from the decoding stage. /// </remarks> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully deserialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> internal abstract void retrieveCall(org.acplt.oncrpc.XdrAble call);
/// <summary>Send back an ONC/RPC reply to the original caller.</summary> /// <remarks> /// Send back an ONC/RPC reply to the original caller. This is rather a /// low-level method, typically not used by applications. Dispatcher handling /// ONC/RPC calls have to use the /// <see cref="OncRpcCallInformation.reply(org.acplt.oncrpc.XdrAble)">OncRpcCallInformation.reply(org.acplt.oncrpc.XdrAble) /// </see> /// method instead on the /// call object supplied to the handler. /// </remarks> /// <param name="callInfo"> /// information about the original call, which are necessary /// to send back the reply to the appropriate caller. /// </param> /// <param name="state"> /// ONC/RPC reply message header indicating success or failure /// and containing associated state information. /// </param> /// <param name="reply"> /// If not <code>null</code>, then this parameter references /// the reply to be serialized after the reply message header. /// </param> /// <exception cref="org.acplt.oncrpc.OncRpcException"> /// if an ONC/RPC exception occurs, like the data /// could not be successfully serialized. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O exception occurs, like transmission /// failures over the network, etc. /// </exception> /// <seealso cref="OncRpcCallInformation">OncRpcCallInformation</seealso> /// <seealso cref="OncRpcDispatchable">OncRpcDispatchable</seealso> internal override void reply(org.acplt.oncrpc.server.OncRpcCallInformation callInfo , org.acplt.oncrpc.server.OncRpcServerReplyMessage state, org.acplt.oncrpc.XdrAble reply) { beginEncoding(callInfo, state); if (reply != null) { reply.xdrEncode(sendingXdr); } endEncoding(); }