Manual Chapter : Generic Message Example

Applies To:

Show Versions Show Versions

BIG-IP LTM

  • 15.0.1, 15.0.0, 14.1.2, 14.1.0, 14.0.1, 14.0.0, 13.1.3, 13.1.1, 13.1.0
Manual Chapter
 

Generic Message Example

This section provides an example of using Generic Message to implement a simple chat client.

Each new connection will be asked for the peer's name. The provided name will be used to add a dynamic route to the route table.

Subsequent text entered will be treated as a request or response message. Requests are of the form: "<destination>:<text>\n". Responses do not contain a destination. A response message will be routed to the originator of the oldest request received.

BIG-IP Configuration

ltm pool gm_pool {
    members {
        10.1.1.100:1234 {
            address 10.1.1.100
        }
    }
}
  
ltm message-routing generic peer default_peer {
    pool gm_pool
    transport-config my_tc
}
ltm message-routing generic protocol my_gm_proto {
    app-service none
    disable-parser yes
}
ltm message-routing generic route default_route {
    peers {
        default_peer
    }
}
ltm message-routing generic router my_gm_router {
    app-service none
    routes {
        default_route
    }
}
ltm message-routing generic transport-config my_tc {
    ip-protocol tcp
    profiles {
        my_gm_proto { }
        tcp { }
    }
    rules {
        gm_rule
    }
}
  
ltm virtual gm_vs {
    destination 10.1.1.50:1234
    ip-protocol tcp
    mask 255.255.255.255
    profiles {
        my_gm_proto { }
        my_gm_router { }
        tcp { }
    }
    rules {
        gm_rule
    }
    source 0.0.0.0/0
    vs-index 2
}
  
ltm rule gm_rule {
    when CLIENT_ACCEPTED {
        TCP::respond "What is your name\n"
        TCP::collect
        set capture_name 1
    }
  
    when SERVER_CONNECTED {
        TCP::respond "What do you wish to be called\n"
        TCP::collect
        set capture_name 1
    }
  
    when CLIENT_DATA {
        set lines [split [TCP::payload] "\n"]
        TCP::payload 0 0
        foreach line $lines {
            set line [string trim $line]
            if { [string length $line] > 0 } {
                if { $capture_name == 1 } {
                    GENERICMESSAGE::peer name $line
                    set capture_name 0
                    TCP::respond "Welcome [GENERICMESSAGE::peer name]\n"
                } else {
                    set tokens [split $line ":"]
                    if {[llength $tokens] > 1} {
                        GENERICMESSAGE::message create [join [lrange $tokens 1 end] ":"] [lindex $tokens 0]
                    } else {
                        GENERICMESSAGE::message create $line
                    }
                }
            }
        }
        TCP::release
        TCP::collect
    }
  
    when SERVER_DATA {
        set lines [split [TCP::payload] "\n"]
        TCP::payload 0 0
        foreach line $lines {
            set line [string trim $line]
            if { [string length $line] > 0 } {
                if { $capture_name == 1 } {
                    GENERICMESSAGE::peer name $line
                    set capture_name 0
                    TCP::respond "Welcome [GENERICMESSAGE::peer name]\n"
                } else {
                    set tokens [split $line ":"]
                    if {[llength $tokens] > 1} {
                        GENERICMESSAGE::message create [join [lrange $tokens 1 end] ":"] [lindex $tokens 0]
                    } else {
                        GENERICMESSAGE::message create $line
                    }
                }
            }
        }
        TCP::release
        TCP::collect
    }
  
    when GENERICMESSAGE_INGRESS {
#        TCP::respond "GM_INGRESS is_request [GENERICMESSAGE::message is_request] req_seq_num [GENERICMESSAGE::message request_sequence_number]\n"
    }
  
    when MR_INGRESS {
#        TCP::respond "MR_INGRESS src: [GENERICMESSAGE::message src] dest [GENERICMESSAGE::message dest] lasthop [MR::message lasthop] nexthop: [MR::message nexthop]\n"
    }
  
  
    when GENERICMESSAGE_EGRESS {
#        TCP::respond "GM_EGRESS status: [GENERICMESSAGE::message status] is_request [GENERICMESSAGE::message is_request] req_seq_num [GENERICMESSAGE::message request_sequence_number]\n"
        TCP::respond "[GENERICMESSAGE::message data]\n"
    }
}

Client Server Configuration

 
Server

Execute the following command (with local IP address):

nc -l 10.1.1.100 1234

Client

Execute the following command (with local IP address):

telnet 10.1.1.50 1234

Communication Dialogue

The following example illustrates communication between different clients and a server. The example traverses down with time. Text entered is in courier.

Table 1. Communication Dialog
Client A Client B Server Notes

What is your name

Alex

Welcome Alice

What is your name

Bob

Welcome Bob

  Both clients connect and provide their routing name
Bob: Are you there     Request sent to route Bob (Req 1)
 

Are you there

Yes, who is this?

 

Request displayed (Req 1)

Response (there is no destination provided), so it is routed to the originator of the oldest request (Rsp 1)

Yes, who is this?

Bob: This is Alex

   

Response delivered (Rsp 1)

New request (Req 2)

 

This is Alice

Alex: hello Alex

 

Request delivered (Req 2)

New request (Req 3)

hello Alex     Request delivered (Req 3)
  Charlie: Are you there?   New request (Req 4), destination does not match any existing routes so the default route is selected.
   

What do you wish to be called

Dave

Welcome Dave

New connection established to pool member of default route
   

Are you there?

Yes, who is this?

Request delivered (Req 4)

Response to Req 4 (Rsp 4)

 

Yes, who is this?

Bob

 

Response delivered (Rsp 4)

Since there is no destination, this is a response. This will be matched to the oldest pending request on this connection which is Req 2 (Rsp 2)

Bob     Response to Req 2 delivered (Rsp 2)