aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/provdisc/dhcp/DHCPTransaction.java
blob: e2493cff890a70e29b4d444021320e4804df968d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.sip.communicator.impl.provdisc.dhcp;

import java.net.*;
import java.util.*;

import net.java.sip.communicator.util.*;

/**
 * DHCP transaction class.
 *
 * @author Sebastien Vincent
 */
public class DHCPTransaction
{
    /**
     * Logger.
     */
    private final Logger logger
        = Logger.getLogger(DHCPTransaction.class);

    /**
     * Number of retransmission before giving up.
     */
    private int maxRetransmit = 2;

    /**
     * Current number of retransmission.
     */
    private int nbRetransmit = 0;

    /**
     * Fix interval for retransmission. This final interval will be obtained
     * by adding a random number between [-1, 1].
     */
    private int interval = 2;

    /**
     * The Timer that will trigger retransmission.
     */
    private Timer timer = null;

    /**
     * The DHCP packet content.
     */
    private final DatagramPacket message;

    /**
     * The socket that will be used to retransmit DHCP packet.
     */
    private final DatagramSocket sock;

    /**
     * Constructor.
     *
     * @param sock UDP socket
     * @param message DHCP packet content
     */
    public DHCPTransaction(DatagramSocket sock, DatagramPacket message)
    {
        this.sock = sock;
        this.message = message;
        this.timer = new Timer();
    }

    /**
     * Schedule a timer for retransmission.
     *
     * @throws Exception if message cannot be sent on the socket
     */
    public void schedule() throws Exception
    {
        sock.send(message);

        /* choose a random between [-1, 1] */
        int rand = new Random().nextInt(2) - 1;
        timer.schedule(new RetransmissionHandler(), (interval + rand) * 1000);
    }

    /**
     * Cancel the transaction (i.e stop retransmission).
     */
    public void cancel()
    {
        timer.cancel();
    }

    /**
     * Set the maximum retransmission for a transaction.
     *
     * @param maxRetransmit maximum retransmission for this transaction
     */
    public void setMaxRetransmit(int maxRetransmit)
    {
        this.maxRetransmit = maxRetransmit;
    }

    /**
     * Set the fixed interval for retransmission.
     *
     * @param interval interval to set
     */
    public void setInterval(int interval)
    {
        this.interval = interval;
    }

    /**
     * A <tt>TimerTask</tt> that will handle retransmission of DHCP INFORM.
     *
     * @author Sebastien Vincent
     */
    private class RetransmissionHandler
        extends TimerTask
    {
        /**
         * Thread entry point.
         */
        @Override
        public void run()
        {
            int rand = new Random().nextInt(2) - 1;

            try
            {
                sock.send(message);
            }
            catch(Exception e)
            {
                logger.warn("Failed to send DHCP packet", e);
            }

            nbRetransmit++;
            if(nbRetransmit < maxRetransmit)
            {
                timer.schedule(new RetransmissionHandler(),
                        (interval + rand) * 1000);
            }
        }
    };
}