I'm currently developing an Embedded device, which uses TCP-IP, and get's it's IP address with DHCP.
I saw in examples, that every now and then, I need to check if the lease has ended, but I didn't find any reference about how often to check it, because there are implementation who check it once in 8 days, and implementation which check it every 24 hours.
so basically, in your implementations, How often do you check the DHCP lease ? what's the standard regarding this issue ?
You actually have to check the "IP Lease time" field in the ACK of the DHCPREQUEST. The RFC specifies that this ACK message MUST contain the lease time. Some clients may also choose to propose a lease time in the DHCPDISCOVER or DHCPREQUEST message (depends on the implementation).
From the client perspective, at 50% of the lease duration (T1) the client has to send a DHCP Request to the server to ask for a renew of its lease time. When the client receives a DHCP ACK from the server, the client computes the lease expiration time as the sum of the time at which the client sent the DHCPREQUEST message and the duration of the lease in the DHCPACK message.
If no DHCPACK arrives before time by 87.5% of lease time (T2), the client sends (via broadcast) a DHCPREQUEST message to extend its lease.
If the lease expires before the client receives a DHCPACK (T3), the client MUST immediately stop any other network processing and requests network initialization parameters as if the client were uninitialized.
Hence you have to keep in mind T1, T2 and T3.
Related
Let's suppose 2 computers:
The first is running a netcat server on a tcp port.
The second is running a netcat client, connected to the previous netcat server.
(netcat is an example, you can imagine a basic c program with socket)
We ca send data between the 2 computers.
Let's imagine nobody send data during multiple days.
Is there a timeout in tcp stack ?
Does netcat (or operating system) sends some packets to keep the connection opened ?
What i want to know is how much data is sent if there is no top level activity.
Thanks
Is there a timeout in tcp stack ?
There are many different timeouts in the TCP stack, depending on what state we are currently in, and how the connection was configured (e.g. with keepalive or not). The idle connection timeout (which is what you refer to) does not seem to be defined. With keepalive the timeout is ~2 hours. That being said pretty much every firewall in the world will setup some timeout. Based on this reddit thread 15 minutes looks like a reasonable assumption, maybe even 1 hour. But multiple days? I doubt it will be alive in any network (except your own).
Does netcat (or operating system) sends some packets to keep the connection opened ?
No. You will have to do it yourself by sending data. With the keepalive option for TCP, the OS will do it for you (note: keepalive is disabled by default), but this works between direct peers, i.e. may fail when proxies are involved. Sending data is definitely a better approach.
I work on my first IOT POC, the device will usually generate sensor data once per hour/day. I planned to have architecture like this:
- 1 shared topic for sensor data input (device to backend direction)
- Each device will subscribe initially to its own specific topic aka /device/{id}/notification
Now, after sensor data submitted to shared topic, I plan to put device into deep sleep (device can only be waked-up by wifi packet or timer), in this state TCP connection to broker is lost.
Question: After device is back waked-up and TCP connection to MQTT broker is re-established, will the device receive all messages which were generated by server during out-of-service period, or these messages won't be available?
During client connecting to the broker, the CleanSession flag enables the broker to queue up missed messages of QoS 1 or QoS 2 (storing QoS 0 messages is implementation-dependent).
The MQTT 3.1.1 Standard Section 3.1.2.4 specifies that:
If CleanSession is set to 0, the Server MUST resume communications with the Client based on state from the current Session (as identified by the Client identifier). If there is no Session associated with the Client identifier the Server MUST create a new Session. The Client and Server MUST store the Session after the Client and Server are disconnected [MQTT-3.1.2-4]. After the disconnection of a Session that had CleanSession set to 0, the Server MUST store further QoS 1 and QoS 2 messages that match any subscriptions that the client had at the time of disconnection as part of the Session state [MQTT-3.1.2-5]. It MAY also store QoS 0 messages that meet the same criteria
The problem with a persistent session is that it may queue up large numbers of messages, so upon re-connection the client is bombarded with missed messages. This may be desirable if you require to know the full sequence of readings, or highly undesirable if the client is running on a low-power, battery-fed embedded device.
To address this, MQTT provides another feature: retained flag in publication messages.
The MQTT 3.1.1 Standard Section 3.3.1.3 specifies that:
If the RETAIN flag is set to 1, in a PUBLISH Packet sent by a Client to a Server, the Server MUST store the Application Message and its QoS, so that it can be delivered to future subscribers whose subscriptions match its topic name [MQTT-3.3.1-5]. When a new subscription is established, the last retained message, if any, on each matching topic name MUST be sent to the subscriber [MQTT-3.3.1-6]. If the Server receives a QoS 0 message with the RETAIN flag set to 1 it MUST discard any message previously retained for that topic. It SHOULD store the new QoS 0 message as the new retained message for that topic, but MAY choose to discard it at any time - if this happens there will be no retained message for that topic
This ensures that upon re-connection the client receives only the latest message on a given topic.
Very quickly I found an answer by myself. Persistent Session is the anwer. I was looking for persistent subscription and wasn't initially successful...
Here is finally great article about my case:
http://www.hivemq.com/blog/mqtt-essentials-part-7-persistent-session-queuing-messages
So yes, persistent subscriptions is called persistent sessions and yes it is possible.
We have a shell script setup on one Unix box (A) that remotely calls a web service deployed on another box (B). On A we just have the scripts, configurations and the Jar file needed for the classpath.
After the batch job is kicked off, the control is passed over from A to B for the transactions to happen on B. Usually the processing is finished on B in less than an hour, but in some cases (when we receive larger data for processing) the process continues for more than an hour. In those cases the firewall tears down the connection between the 2 hosts after an inactivity of 1 hour. Thus, the control is never returned back from B to A and we are not notified that the batch job has ended.
To tackle this, our network team has suggested to implement keep-alives at the application level.
My question is - where should I implement those and how? Will that be in the web service code or some parameters passed from the shell script or something else? Tried to google around but could not find much.
You basically send an application level message and wait for a response to it. That is, your applications must support sending, receiving and replying to those heart-beat messages. See FIX Heartbeat message for example:
The Heartbeat monitors the status of the communication link and identifies when the last of a string of messages was not received.
When either end of a FIX connection has not sent any data for [HeartBtInt] seconds, it will transmit a Heartbeat message. When either end of the connection has not received any data for (HeartBtInt + "some reasonable transmission time") seconds, it will transmit a Test Request message. If there is still no Heartbeat message received after (HeartBtInt + "some reasonable transmission time") seconds then the connection should be considered lost and corrective action be initiated....
Additionally, the message you send should include a local timestamp and the reply to this message should contain that same timestamp. This allows you to measure the application-to-application round-trip time.
Also, some NAT's close your TCP connection after N minutes of inactivity (e.g. after 30 minutes). Sending heart-beat messages allows you to keep a connection up for as long as required.
I'm connecting to remote server with persistent connection, and the network devices between me and remote server use VRRP to create a VIP and do fail-over when one device or link failed.
Will the fail-over cause TCP connection broken and I need to handle such a situation to re-connect remote server, or I can ignore this, just like vmware's VMotion?
It depends on the application keepalive, and VRRP advertisement interval setting. But most likely it should be OK to ignore it.
Failover is the most important feature of VRRP to make sure that hosts using the VIP get minimal impact when there is an outage (e.g. the Master VRRP router goes down). That said, there is still an impact, which is loss of connectivity via the VIP.
You can check the VRRP configuration to estimate the duration of that loss. If VRRP advertisement interval (i.e. keepalive interval) is configured to be 1second (which is the default value for both version 2 and 3), then it'll take 1second * 3 = 3 seconds for the backup node to detect the failure, plus some time for the backup to change its state to master. So in total between 3-4 seconds. if the advertisement interval is shorter than that, the time of the no connectivity will also be shorter, following the same formula described here.
So the question really is, what would happen during the time of no connectivity to outside the LAN? TCP
inherently doesn't mind idle time of 3 seconds or any duration once the connection is established, so as long as the VRRP failover completes, TCP will not have noticed anything.
However, the application may implement its own keepalive to monitor the connection over TCP. And if that interval is shorter than VRRP advertisement interval, it may think there is a breakage of connection during the VRRP failover. But it should be rare that an application would set its keepalive to be as short as a few seconds. E.g., for SSH, it's usually set to 60 seconds.
In sum, it shouldn't be a problem. But if it is, check settings on both application keepalive and VRRP advertisement interval and adjust as needed. Note that you may not want the VRRP advertisement interval to be too short as it would generates more keepalives than necessary, which uses LAN bandwidth.
I am trying to understand the relation between TCP/IP and HTTP timeout values. Are these two timeout values different or same? Most Web servers allow users to set the HTTP Keep Alive timeout value through some configuration. How is this value used by the Web servers? is this value just set on the underlying TCP/IP socket i.e is the HTTP Keep Alive timeout and TCP/IP Keep Alive Timeout same? or are they treated differently?
My understanding is (maybe incorrect):
The Web server uses the default timeout on the underlying TCP socket (i.e. indefinite) regardless of the configured HTTP Keep Alive timeout and creates a Worker thread that counts down the specified HTTP timeout interval. When the Worker thread hits zero, it closes the connection.
EDIT:
My question is about the relation or difference between the two timeout durations i.e. what will happen when HTTP keep-alive timeout duration and the timeout on the Socket (SO_TIMEOUT) which the Web server uses is different? should I even worry about these two being same or not?
An open TCP socket does not require any communication whatsoever between the two parties (let's call them Alice and Bob) unless actual data is being sent. If Alice has received acknowledgments for all the data she's sent to Bob, there's no way she can distinguish among the following cases:
Bob has been unplugged, or is otherwise inaccessible to Alice.
Bob has been rebooted, or otherwise forgotten about the open TCP socket he'd established with Alice.
Bob is connected to Alice, and knows he has an open connection, but doesn't have anything he wants to say.
If Alice hasn't heard from Bob in awhile and wants to distinguish among the above conditions, she can resend her last byte of data, wrapped in a suitable TCP frame to be recognizable as a retransmission, essentially pretending she hasn't heard the acknowledgment. If Bob is unplugged, she'll hear nothing back, even if she repeatedly sends the packet over a period of many seconds. If Bob has rebooted or forgotten the connection, he will immediately respond saying the connection is invalid. If Bob is happy with the connection and simply has nothing to say, he'll respond with an acknowledgment of the retransmission.
The Timeout indicates how long Alice is willing to wait for a response when she sends a packet which demands a reply. The Keepalive time indicates how much time she should allow to lapse before she retransmits her last bit of data and demands an acknowledgment. If Bob goes missing, the sum of the Keepalive and Timeout values will indicate the worst-case time between Alice receiving her last bit of data and her deciding that Bob is dead.
They're two separate mechanisms; the name is a coincidence.
HTTP keep-alive (also known as persistent connections) is keeping the TCP socket open so that another request can be made without setting up a new connection.
TCP keep-alive is a periodic check to make sure that the connection is still up and functioning. It's often used to assure that a NAT box (e.g., a DSL router) doesn't "forget" the mapping between an internal and external ip/port.
KeepAliveTimeout Directive
Description: Amount of time the server will wait for subsequent
requests on a persistent connection Syntax: KeepAliveTimeout seconds
Default: KeepAliveTimeout 15 Context: server config, virtual host
Status: Core Module: core The number of seconds Apache will wait for a
subsequent request before closing the connection. Once a request has
been received, the timeout value specified by the Timeout directive
applies.
Setting KeepAliveTimeout to a high value may cause performance
problems in heavily loaded servers. The higher the timeout, the more
server processes will be kept occupied waiting on connections with
idle clients.
In a name-based virtual host context, the value of the first defined
virtual host (the default host) in a set of NameVirtualHost will be
used. The other values will be ignored.
TimeOut Directive
Description: Amount of time the server will wait for certain events
before failing a request Syntax: TimeOut seconds Default: TimeOut 300
Context: server config, virtual host Status: Core Module: core The
TimeOut directive currently defines the amount of time Apache will
wait for three things:
The total amount of time it takes to receive a GET request. The amount
of time between receipt of TCP packets on a POST or PUT request. The
amount of time between ACKs on transmissions of TCP packets in
responses. We plan on making these separately configurable at some
point down the road. The timer used to default to 1200 before 1.2, but
has been lowered to 300 which is still far more than necessary in most
situations. It is not set any lower by default because there may still
be odd places in the code where the timer is not reset when a packet
is sent.