Solstice X.25 9.2 Developer's Guide

12.5.4 Out-of-Band Data

Out-of-band data is managed by a combination of ioctl calls, the passing of the MSG_OOB flag to recv, and an optional signal, SIGURG. To determine whether out-of-band data has been received, call the X25_OOB_TYPE ioctl:

ints, oob_type;
 error = ioctl(s, X25_OOB_TYPE, &oob_type); 

If out-of-band data does not exist, oob_type is set to zero. Otherwise, oob_type is set to a value indicating the type of out-of-band data that has been received. The types of out-of-band data are:

#define INT_DATA      30   /* interrupt data */
 #define VC_RESET      32   /* virtual circuit reset */ 

INT_DATA indicates that interrupt data has been received. The interrupt data is read by calling recv with flags set to MSG_OOB. In general, the following sequence occurs upon receipt of an interrupt packet:

  1. X.25 receives an interrupt request packet. The interrupt is queued and causes a SIGURG signal.

  2. The user reads the interrupt packet (with recv), automatically causing an Interrupt Confirmation packet to be sent.

    Up to 32 bytes of interrupt data may be received if the interface supports 1984 X.25.

    It is not necessary to issue a recv call with flags set to MSG_OOB if the interrupt type is something other than INT_DATA.

    VC_RESET indicates that the virtual circuit associated with the socket has been reset.

    The SunNet X.25 7.0 interface had an additional type of out-of-band data, MSG_TOO_LONG, which indicated that a message was discarded because of the socket buffer limitations. This type of out-of-band data does not exist in the current release, because an X.25 message will not get discarded when it gets too long. "Too long" means that too many packets are received with the M-bit set to 1 and the user has not asked for individual packets with the X25_HEADER ioctl. Instead of getting discarded, the X.25 message will be sent upstream as soon as its length goes over MAXNSDULEN, whether or not the end of the message has been seen (that is, a packet with the M-bit set to 0). MAXNSDULEN is one of the configurable Layer 3 parameters described in Solstice X.25 9.2 Administration Guide.

    If this happens, there are three possible courses of action that may be taken:

    • Increase the socket high water mark using the X25_WR_SBHIWAT ioctl to a maximum of 32767.

    • Request a header on every packet using the X25_HEADER ioctl. This will result in every packet being returned to the user with an extra header byte.

    • Use the X25_RECORD_SIZE ioctl to specify the maximum number of full packets in a complete X.25 message that X.25 should receive before returning the accumulated data to the user as a record.

      Out-of-band messages are serialized in a FIFO (first in, first out) queue, except for interrupt data, which preempts all other out-of-band messages. If the ioctl call X25_OOB_TYPE indicates INT_DATA, then the interrupt packet will be the next packet read on the out-of-band channel, that is, when recv is called with flags set to MSG_OOB. The INT_DATA condition remains true until the out-of-band packet has been read.

      The following piece of code may be used to set up the function func as the signal handler for the SIGURG signal:

      int func();
       (void) signal(SIGURG, func); 

      The signal SIGURG, which indicates an urgent condition present on a socket, may be enabled to indicate an abnormal condition or the arrival of abnormal data at an AF_X25 socket. The signal causes func, the signal handler procedure, to be called. The signal procedure must be called before connect on the calling side and listen on the called side.

      A process receiving the SIGURG signal must examine all potential causes for the signal in order to identify the source of the signal. For example, if a process has multiple AF_X25 sockets open when it receives the SIGURG signal, each open AF_X25 socket will have to be queried with the X25_OOB_TYPE ioctl to determine the signal source. It could well be that the signal did not originate with X.25, but from some other source.

      Upon socket creation, the socket is not associated with a process group ID. If a signal handler routine is used, the user should associate a proper process group ID with the socket as shown below:

      int pgrp, error;
       pgrp = getpid(); /* get the current process id */
       error = ioctl(s, SIOCSPGRP, &pgrp); 

      When a signal handler routine is awakened, pending system calls, for example, recv, accept, connect, select, etc., will be aborted with errno set to EINTR (interrupted system call). The signal handler routine func may be disabled at any time by assigning a default action SIG_DFL to SIGURG:

      (void) signal(SIGURG, SIG_DFL); 

      A more general explanation of signals is in the SunOS 4.x documentation on socket programming.