Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Execution of the function

&pagelevel(4)&pagelevel

New subfunctions for sendmsg(), recvmsg(), setsockopt() and getsockopt() are provided for this functionality.

To achieve this, the following structures are required in the header file sys.socket.h:

/*
 * struct instead of cmsghdr in case of Handoff-Handling
*/
 
struct red_info_tcp {
        short   fd;                          /* file descriptor  (listener)          */
        short   port;                        /* port number                          */
        short   domain;                      /* address family                       */
        short   flags;                       /* flags of success                     */
        int     cid;                         /* cid                                  */
        int     if_index;                    /* interface index listener process     */
        int     rwindow;                     /* max read  window                     */
        int     wwindow;                     /* max write window                     */
};
struct red_info_iso {
        short   fd;                          /* file descriptor  (listener)          */
        short   domain;                      /* address family                       */
        short   flags;                       /* flags of success                     */
        short   tsellen;                     /* length of TSEL                       */
        int     rwindow;                     /* max read  window                     */
        int     wwindow;                     /* max write window                     */
        char    tsel[32];                    /* TSEL application                     */
        char    tesn[8];                     /* TESN hostname                        */
};
struct red_info_svrs {
        short   domain;                      /* domain    (server[accept])           */
        short   fd_server;                   /* file descriptor(server[accept])      */
        int     tsor_server;                 /* tsap_open_reference 1. server_socket */
        int     cref_server;                 /* cref server[accept]_socket           */
};
struct cmsg_redhdr {
        u_int   cmsg_len;                    /* data byte count, including hdr       */
        int     cmsg_level;                  /* originating protocol                 */
        int     cmsg_type;                   /* protocol-specific type of operation  */
        union {
        char    tsap_name[TSAPNAMMAXLEN];    /* needed tsap_name for shared tsap     */
        struct  red_info_iso red_liso;       /* needed tsap_name for iso shared tsap */
        struct  red_info_tcp red_ltcp;       /* Info of listen socket                */
        struct  red_info_tcp red_ctcp;       /* Info of client                       */
        struct  red_info_svrs red_svrs;      /* Info of server socket ("accept")     */
       } cmsg_redhdr_info;
        short   bind_ok;                     /* open shared TSAP successfull         */
        short   handoff_ok;                  /* handoff successfull                  */
        short   tsap_name_len;               /* length of tsap_name                  */
        short   fd_server;                   /* file descriptor redirected socket    */
        short   domain;                      /* address family                       */
        int     tsn;                         /* tsn server-process                   */
#define  redhdr_tsap_name          cmsg_redhdr_info.tsap_name
#define  redhdr_red_liso           cmsg_redhdr_info.red_liso
#define  redhdr_red_ltcp           cmsg_redhdr_info.red_ltcp
#define  redhdr_red_ctcp           cmsg_redhdr_info.red_ctcp
#define  redhdr_red_svrs           cmsg_redhdr_info.red_svrs
};

Execution sequence

Acceptance: client = C, listener = L, server = S
The listen socket of listener L has the file descriptor fd = 1.

A connection under the AF_ISO domain is established between listener L and server S usingfd 0 on the listener side and fd 0 on the server side. This connection can be established either in blocking mode or in non-blocking mode.

In non-blocking mode, it is mandatory for pending events to be polled using select() or soc_poll().

The AF_ISO listen socket on the server side has the fd 0. The endpoint is moved in the following stages:

  1. C establishes a connection to L.

  2. The connection is accepted by L and moved to S.

  3. In L, sendmsg() is used to forward to S information on the domain of the connection established by C and the fd of the accept socket for this connection over the local AF_ISO connection.

    int sendmsg(int s, struct msghdr * msg, int flags);

    msg.msg_control is a pointer to a structure of the type cmsg_redhdr.

    The length of struct cmsg_redhdr is entered in msg.msg_control_len.

    cmsg_redhdr.cmsg_len = sizeof(cmsg_redhdr)
    cmsg_redhdr.cmsg_level = SOL_TRANSPORT
    cmsg_redhdr.cmsg_type = TPOPT_REDI_DATA

    The address family of the endpoint to be moved must be entered in cmsg_redhdr.domain and depending on this address family, the fd of the accept socket must be entered in cmsg_redhdr.redhdr_red_liso (for AF_ISO) or cmsg_redhdr.redhdr_red_ltcp (for AF_INET or AF_INET6) in the element fd.

  4. The S side reads from the AF_ISO connection using recvmsg().

    int recvmsg(int s, struct msghdr * msg, int flags);

    msg.msg_control is a pointer to a structure of the type cmsg_redhdr.

    cmsg_redhdr.cmsg_len = sizeof(cmsg_redhdr)
    cmsg_redhdr.cmsg_level = SOL_TRANSPORT
    cmsg_redhdr.cmsg_type = TPOPT_REDI_DATA

    Action on S:

    On the basis of the information from L contained in the structure of the type cmsg_redhdr that has been passed, a new connection endpoint is generated using an internal bind().
    The fd of this endpoint is returned in cmsg_redhdr.fd_server together with the address family in cmsg_redhdr.domain.

  5. The S side passes the information that the new connection endpoint has been created to the L side.

    int sendmsg(int s, struct msghdr * msg, int flags);

    msg.msg_control is a pointer to a structure of the type cmgs_redhdr.

    cmsg_redhdr.cmsg_ len = sizeof(cmsg_redhdr)
    cmsg_redhdr.cmsg_level = SOL_TRANSPORT
    cmsg_redhdr.cmsg_type = TPOPT_REDI_BDOK

    The address family of the socket for the new endpoint must additionally be entered in cmsg_redhdr.domain and the fd of this socket must be entered in cmsg_redhdr.fd_server.

  6. The L side must wait for the information that the new endpoint is available before the end point can actually be moved.

    int recvmsg(int s, struct msghdr * msg, int flags);

    msg.msg_control is a pointer to a structure of the type cmsg_redhdr.

    cmsg_redhdr.cmsg.len = sizeof(struct cmsg_redhdr)
    cmsg_redhdr.cmsg_level = SOL_TRANSPORT
    cmsg_redhdr.cmsg_type = TPOPT_REDI_BDOK

    The address family of the endpoint to be moved must additionally be entered in cmsg_redhdr.domain and depending on this address family, the fd of the accept socket must be entered in cmsg_redhdr.redhdr_red_liso (for AF_ISO) or cmsg_redhdr.redhdr_red_ltcp (for AF_INET or AF_INET6) in the element fd.

    The cmsg_redhdr.bind_ok field can be used to check whether successful creation of the new endpoint on the S side has been acknowledged with REDBIND_OK.

    A data stop is then triggered internally for this connection endpoint. This means that data can be sent from the client, but it is no longer delivered to the old connection end point.

  7. setsockopt() is then issued on the L side to move the functionality of the endpoint. This means that the partner information entered in the accept socket is transferred to the socket of the new end point in the server.

    int setsockopt(int s, int level, int optname, char * optval, int optlen);

    optval is a pointer to a structure of the type cmsg_redhdr.
    level = SOL_TRANSPORT
    optname = TPOPT_REDI_CALL

    cmsg_redhdr.cmsg_len = sizeof(struct cmsg_redhdr)
    cmsg_redhdr.cmsg_level = SOL_TRANSPORT
    cmsg_redhdr.cmsg_type = TPOPT_REDI_CALLgetsockopt()

  8. is issued on the S side to wait for data from the accept socket on the L side.

    int getsockopt(int s, int level, int optname, char * optval, int* optlen);

    optval is a pointer to a structure of the type cmsg_redhdr.
    level = SOL_TRANSPORT
    optname = TPOPT_REDI_CALL

    cmsg_redhdr.cmsg_len = sizeof(struct cmsg_redhdr)
    cmsg_redhdr.cmsg_level = SOL_TRANSPORT
    cmsg_redhdr.cmsg_type = TPOPT_REDI_CALL

    The address family must be entered in cmsg_redhdr.domain and the fd of the socket for the new endpoint must be entered in cmsg_redhdr.fd_server.

    Once the event has been received and picked up, the connection environment is finally established and the data stop for the connection is canceled. This means that data is now delivered to the new connection endpoint.

    The accept socket of the original endpoint can now be closed with soc_close(), as can the AF_ISO connection for handoff communication.