Sunday, September 23, 2012

TCP Connection Termination

Source: http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm

Normal Connection Termination
In the normal case, each side terminates its end of the connection by sending a special message with the FIN (finish) bit set. This message, sometimes called a FIN, serves as a connection termination request to the other device, while also possibly carrying data like a regular segment. The device receiving the FIN responds with an acknowledgment to the FIN to indicate that it was received. The connection as a whole is not considered terminated until both sides have finished the shut down procedure by sending a FIN and receiving an ACK.
Thus, termination isn't a three-way handshake like establishment: it is a pair of two-way handshakes. The states that the two devices in the connection move through during a normal connection shutdown are different because the device initiating the shutdown must behave differently than the one that receives the termination request. In particular, the TCP on the device receiving the initial termination request must inform its application process and wait for a signal that the process is ready to proceed. The initiating device doesn't need to do this, since the application is what started the ball rolling in the first place.
Key Concept: A TCP connection is normally terminating using a special procedure where each side independently closes its end of the link. It normally begins with one of the application processes signalling to its TCP layer that the session is no longer needed. That device sends a FIN message to tell the other device that it wants to end the connection, which is acknowledged. When the responding device is ready, it too sends a FIN that is acknowledged; after waiting a period of time for the ACK to be received, the session is closed.

Table 154 describes in detail how the connection termination process works; the progression of states and messages exchanged can also be seen in Figure 214. The table is adapted from Table 151, describing the TCP finite state machine, but shows what happens for both the server and the client over time during connection shutdown. Either device can initiate connection termination; in this example I am assuming the client does it. Each row shows the state each device begins in, what action it takes in that state and what state to which it transitions. I have also shown the send and receive stages of both of the steps for each of the client and server’s close operations.


Table 154: TCP Connection Termination Procedure
Client
Server
Start State
Action
Transitions To State
Start State
Action
Transitions To State
ESTABLISHED
Client Close Step #1 Transmit: The application using TCP signals that the connection is no longer needed. The client TCP sends a segment with the FIN bit set to request that the connection be closed.
FIN-WAIT-1
ESTABLISHED
At this stage the server is still in normal operating mode.
FIN-WAIT-1
The client, having sent a FIN, is waiting for it to both be acknowledged and for the serve to send its own FIN. In this state the client can still receive data from the server but will no longer accept data from its local application to be sent to the server.
ESTABLISHED
Client Close Step #1 Receive and Step #2 Transmit: The server receives the client's FIN. It sends an ACK to acknowledge the FIN. The server must wait for the application using it to be told the other end is closing, so the application here can finish what it is doing.
CLOSE-WAIT
FIN-WAIT-1
Client Close Step #2 Receive: The client receives the ACK for its FIN. It must now wait for the server to close.
FIN-WAIT-2
CLOSE-WAIT
The server waits for the application process on its end to signal that it is ready to close.
FIN-WAIT-2
The client is waiting for the server's FIN.
CLOSE-WAIT
Server Close Step #1 Transmit: The server's TCP receives notice from the local application that it is done. The server sends its FIN to the client.
LAST-ACK
FIN-WAIT-2
Server Close Step #1 Receive and Step #2 Transmit: The client receives the server's FIN and sends back an ACK.
TIME-WAIT
LAST-ACK
The server is waiting for an ACK for the FIN it sent.
TIME-WAIT
The client waits for a period of time equal to double the maximum segment life (MSL) time, to ensure the ACK it sent was received.
LAST-ACK
Server Close Step #2 Receive: The server receives the ACK to its FIN and closes the connection.
CLOSED
TIME-WAIT
The timer expires after double the MSL time.
CLOSED
CLOSED
The connection is closed on the server's end.

CLOSED
The connection is closed.

CLOSED
The connection is closed.






Saturday, September 22, 2012

Active FTP vs. Passive FTP, a Definitive Explanation

Source: http://slacksite.com/other/ftp.html


The Basics

FTP is a TCP based service exclusively. There is no UDP component to FTP. FTP is an unusual service in that it utilizes two ports, a 'data' port and a 'command' port (also known as the control port). Traditionally these are port 21 for the command port and port 20 for the data port. The confusion begins however, when we find that depending on the mode, the data port is not always on port 20.

Active FTP

In active mode FTP the client connects from a random unprivileged port (N > 1023) to the FTP server's command port, port 21. Then, the client starts listening to port N+1 and sends the FTP command PORT N+1 to the FTP server. The server will then connect back to the client's specified data port from its local data port, which is port 20.
From the server-side firewall's standpoint, to support active mode FTP the following communication channels need to be opened:
  • FTP server's port 21 from anywhere (Client initiates connection)
  • FTP server's port 21 to ports > 1023 (Server responds to client's control port)
  • FTP server's port 20 to ports > 1023 (Server initiates data connection to client's data port)
  • FTP server's port 20 from ports > 1023 (Client sends ACKs to server's data port)

Passive FTP

In order to resolve the issue of the server initiating the connection to the client a different method for FTP connections was developed. This was known as passive mode, or PASV, after the command used by the client to tell the server it is in passive mode.
In passive mode FTP the client initiates both connections to the server, solving the problem of firewalls filtering the incoming data port connection to the client from the server. When opening an FTP connection, the client opens two random unprivileged ports locally (N > 1023 and N+1). The first port contacts the server on port 21, but instead of then issuing a PORT command and allowing the server to connect back to its data port, the client will issue the PASVcommand. The result of this is that the server then opens a random unprivileged port (P > 1023) and sends the PORT P command back to the client. The client then initiates the connection from port N+1 to port P on the server to transfer data.
From the server-side firewall's standpoint, to support passive mode FTP the following communication channels need to be opened:
  • FTP server's port 21 from anywhere (Client initiates connection)
  • FTP server's port 21 to ports > 1023 (Server responds to client's control port)
  • FTP server's ports > 1023 from anywhere (Client initiates data connection to random port specified by server)
  • FTP server's ports > 1023 to remote ports > 1023 (Server sends ACKs (and data) to client's data port)

Thursday, September 6, 2012

Linux bash shell comparison

Source: http://tldp.org/LDP/abs/html/comparison-ops.html

7.3. Other Comparison Operators

A binary comparison operator compares two variables or quantities. Note that integer and string comparison use a different set of operators.
integer comparison
-eq
is equal to
if [ "$a" -eq "$b" ]
-ne
is not equal to
if [ "$a" -ne "$b" ]
-gt
is greater than
if [ "$a" -gt "$b" ]
-ge
is greater than or equal to
if [ "$a" -ge "$b" ]
-lt
is less than
if [ "$a" -lt "$b" ]
-le
is less than or equal to
if [ "$a" -le "$b" ]
<
is less than (within double parentheses)
(("$a" < "$b"))
<=
is less than or equal to (within double parentheses)
(("$a" <= "$b"))
>
is greater than (within double parentheses)
(("$a" > "$b"))
>=
is greater than or equal to (within double parentheses)
(("$a" >= "$b"))
string comparison
=

is equal to
if [ "$a" = "$b" ]
CautionNote the whitespace framing the =.
if [ "$a"="$b" ] is not equivalent to the above.
==
is equal to
if [ "$a" == "$b" ]
This is a synonym for =.
NoteThe == comparison operator behaves differently within a double-brackets test than within single brackets.
[[ $a == z* ]]   # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

[ $a == z* ]     # File globbing and word splitting take place.
[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).

# Thanks, Stéphane Chazelas
!=
is not equal to
if [ "$a" != "$b" ]
This operator uses pattern matching within a [[ ... ]] construct.
<
is less than, in ASCII alphabetical order
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ]
Note that the "<" needs to be escaped within a [ ] construct.
>
is greater than, in ASCII alphabetical order
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]
Note that the ">" needs to be escaped within a [ ] construct.
See Example 27-11 for an application of this comparison operator.
-z
string is null, that is, has zero length
 String=''   # Zero-length ("null") string variable.

if [ -z "$String" ]
then
  echo "\$String is null."
else
  echo "\$String is NOT null."
fi     # $String is null.
-n
string is not null.
CautionThe -n test requires that the string be quoted within the test brackets. Using an unquoted string with ! -z, or even just the unquoted string alone within test brackets (seeExample 7-6) normally works, however, this is an unsafe practice. Always quote a tested string. [1]
Example 7-5. Arithmetic and string comparisons
#!/bin/bash

a=4
b=5

#  Here "a" and "b" can be treated either as integers or strings.
#  There is some blurring between the arithmetic and string comparisons,
#+ since Bash variables are not strongly typed.

#  Bash permits integer operations and comparisons on variables
#+ whose value consists of all-integer characters.
#  Caution advised, however.

echo

if [ "$a" -ne "$b" ]
then
  echo "$a is not equal to $b"
  echo "(arithmetic comparison)"
fi

echo

if [ "$a" != "$b" ]
then
  echo "$a is not equal to $b."
  echo "(string comparison)"
  #     "4"  != "5"
  # ASCII 52 != ASCII 53
fi

# In this particular instance, both "-ne" and "!=" work.

echo

exit 0
Example 7-6. Testing whether a string is null
#!/bin/bash
#  str-test.sh: Testing null strings and unquoted strings,
#+ but not strings and sealing wax, not to mention cabbages and kings . . .

# Using   if [ ... ]

# If a string has not been initialized, it has no defined value.
# This state is called "null" (not the same as zero!).

if [ -n $string1 ]    # string1 has not been declared or initialized.
then
  echo "String \"string1\" is not null."
else  
  echo "String \"string1\" is null."
fi                    # Wrong result.
# Shows $string1 as not null, although it was not initialized.

echo

# Let's try it again.

if [ -n "$string1" ]  # This time, $string1 is quoted.
then
  echo "String \"string1\" is not null."
else  
  echo "String \"string1\" is null."
fi                    # Quote strings within test brackets!

echo

if [ $string1 ]       # This time, $string1 stands naked.
then
  echo "String \"string1\" is not null."
else  
  echo "String \"string1\" is null."
fi                    # This works fine.
# The [ ... ] test operator alone detects whether the string is null.
# However it is good practice to quote it (if [ "$string1" ]).
#
# As Stephane Chazelas points out,
#    if [ $string1 ]    has one argument, "]"
#    if [ "$string1" ]  has two arguments, the empty "$string1" and "]" 


echo


string1=initialized

if [ $string1 ]       # Again, $string1 stands unquoted.
then
  echo "String \"string1\" is not null."
else  
  echo "String \"string1\" is null."
fi                    # Again, gives correct result.
# Still, it is better to quote it ("$string1"), because . . .


string1="a = b"

if [ $string1 ]       # Again, $string1 stands unquoted.
then
  echo "String \"string1\" is not null."
else  
  echo "String \"string1\" is null."
fi                    # Not quoting "$string1" now gives wrong result!

exit 0   # Thank you, also, Florian Wisser, for the "heads-up".
Example 7-7. zmore
#!/bin/bash
# zmore

# View gzipped files with 'more' filter.

E_NOARGS=85
E_NOTFOUND=86
E_NOTGZIP=87

if [ $# -eq 0 ] # same effect as:  if [ -z "$1" ]
# $1 can exist, but be empty:  zmore "" arg2 arg3
then
  echo "Usage: `basename $0` filename" >&2
  # Error message to stderr.
  exit $E_NOARGS
  # Returns 85 as exit status of script (error code).
fi  

filename=$1

if [ ! -f "$filename" ]   # Quoting $filename allows for possible spaces.
then
  echo "File $filename not found!" >&2   # Error message to stderr.
  exit $E_NOTFOUND
fi  

if [ ${filename##*.} != "gz" ]
# Using bracket in variable substitution.
then
  echo "File $1 is not a gzipped file!"
  exit $E_NOTGZIP
fi  

zcat $1 | more

# Uses the 'more' filter.
# May substitute 'less' if desired.

exit $?   # Script returns exit status of pipe.
#  Actually "exit $?" is unnecessary, as the script will, in any case,
#+ return the exit status of the last command executed.
compound comparison
-a
logical and
exp1 -a exp2 returns true if both exp1 and exp2 are true.
-o
logical or
exp1 -o exp2 returns true if either exp1 or exp2 is true.
These are similar to the Bash comparison operators && and ||, used within double brackets.
[[ condition1 && condition2 ]]
The -o and -a operators work with the test command or occur within single test brackets.
if [ "$expr1" -a "$expr2" ]
then
  echo "Both expr1 and expr2 are true."
else
  echo "Either expr1 or expr2 is false."
fi
CautionBut, as rihad points out:
[ 1 -eq 1 ] && [ -n "`echo true 1>&2`" ]   # true
[ 1 -eq 2 ] && [ -n "`echo true 1>&2`" ]   # (no output)
# ^^^^^^^ False condition. So far, everything as expected.

# However ...
[ 1 -eq 2 -a -n "`echo true 1>&2`" ]       # true
# ^^^^^^^ False condition. So, why "true" output?

# Is it because both condition clauses within brackets evaluate?
[[ 1 -eq 2 && -n "`echo true 1>&2`" ]]     # (no output)
# No, that's not it.

# Apparently && and || "short-circuit" while -a and -o do not.
Refer to Example 8-3, Example 27-17, and Example A-29 to see compound comparison operators in action.

Notes

[1]As S.C. points out, in a compound test, even quoting the string variable might not suffice. [ -n "$string" -o "$a" = "$b" ] may cause an error with some versions of Bash if $string is empty. The safe way is to append an extra character to possibly empty variables, [ "x$string" != x -o "x$a" = "x$b" ] (the "x's" cancel out).