1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.internal.net.ipsec.ike.utils; 17 18 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RETRANSMIT; 19 20 import android.os.Handler; 21 22 import com.android.internal.net.ipsec.ike.message.IkeMessage; 23 24 /** 25 * Retransmitter represents a class that will send a message and trigger delayed retransmissions 26 * 27 * <p>The Retransmitter class will queue retransmission signals on the provided handler. The owner 28 * of this retransmitter instance is expected to wait for the signal, and call retransmit() on the 29 * instance of this class. 30 */ 31 public abstract class Retransmitter { 32 private final Handler mHandler; 33 private final IkeMessage mRetransmitMsg; 34 private int mRetransmitCount = 0; 35 private int[] mRetransmissionTimeouts; 36 Retransmitter(Handler handler, IkeMessage msg, int[] retransmissionTimeouts)37 public Retransmitter(Handler handler, IkeMessage msg, int[] retransmissionTimeouts) { 38 mHandler = handler; 39 mRetransmitMsg = msg; 40 mRetransmissionTimeouts = retransmissionTimeouts; 41 } 42 43 /** 44 * Triggers a (re)transmission. Will enqueue a future retransmission signal on the given handler 45 */ retransmit()46 public void retransmit() { 47 if (mRetransmitMsg == null) { 48 return; 49 } 50 51 // If the failed iteration is beyond the max attempts, clean up and shut down. 52 if (mRetransmitCount >= mRetransmissionTimeouts.length) { 53 handleRetransmissionFailure(); 54 return; 55 } 56 57 send(mRetransmitMsg); 58 59 long timeout = mRetransmissionTimeouts[mRetransmitCount++]; 60 mHandler.sendMessageDelayed(mHandler.obtainMessage(CMD_RETRANSMIT, this), timeout); 61 } 62 63 /** Cancels any future retransmissions */ stopRetransmitting()64 public void stopRetransmitting() { 65 mHandler.removeMessages(CMD_RETRANSMIT, this); 66 } 67 68 /** Retrieves the message this retransmitter is tracking */ getMessage()69 public IkeMessage getMessage() { 70 return mRetransmitMsg; 71 } 72 73 /** 74 * Implementation-provided sender 75 * 76 * <p>For Retransmitter-internal use only. 77 * 78 * @param msg the message to be sent 79 */ send(IkeMessage msg)80 protected abstract void send(IkeMessage msg); 81 82 /** 83 * Callback for implementations to be informed that we have reached the max retransmissions. 84 * 85 * <p>For Retransmitter-internal use only. 86 */ handleRetransmissionFailure()87 protected abstract void handleRetransmissionFailure(); 88 } 89