⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xti.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef lintstatic char *sccsid = "@(#)xti.c	4.2 (ULTRIX)	11/14/90";#endif lint/*********************************************************************** * * Copyright (c) Digital Equipment Corporation, 1990 * All Rights Reserved.  Unpublished - rights reserved * under the copyright laws of the United States. *  * The software contained on this media is proprietary * to and embodies the confidential technology of  * Digital Equipment Corporation.  Possession, use, * duplication or dissemination of the software and * media is authorized only pursuant to a valid written * license from Digital Equipment Corporation. * * RESTRICTED RIGHTS LEGEND   Use, duplication, or  * disclosure by the U.S. Government is subject to * restrictions as set forth in Subparagraph (c)(1)(ii) * of DFARS 252.227-7013, or in FAR 52.227-19, or in * FAR 52.227-14 ALT.III, as applicable. * ***********************************************************************//************************************************************************ *			Modification History				* * *  07/20/87	hu	Original code. *  12/02/87	mcmenemy Added additional library functionality *  01/19/88    mcmenemy Added connection-less support *  02/01/88    mcmenemy clean-up - prepare to release 1st prototype  *                       which includes DECnet Ultrix support *  03/07/88    mcmenemy Update to Revision 2 (24-feb-88) at GRENOBLE *  03/29/88    mcmenemy Fix dynamic indexing. *  04/06/88    mcmenemy Make changes for BL2 *  08/25/88    mcmenemy Update to Final Draft for XPG 3 *  10/09/88    mcmenemy Get rid of clearing some events that will be kernel *  11/09/88    mcmenemy Clean-up (ie. move ENEVENT to socket call and *                       explicitly disable events in T_UNBIND *  11/26/88    mcmenemy Add *_CONOPT support,enhance T_OPTMGMT, finish T_MORE. *  12/01/88    mcmenemy Add t_alloc() and t_free() support. *  12/06/88    mcmenemy Cleanup NSP code ,add XTIXPG4 defines and OSI code. *  01/06/89    mcmenemy Modify t_accept handling of socket address. *  01/08/89    mcmenemy Add AF_OSI code for defer mode in t_listen *  02/02/89    mcmenemy Add code to clear T_DISCONNECT event in t_rcvdis(). *  02/10/89    mcmenemy Clean-up d_table usage. *  02/20/89    mcmenemy Add additional error return from t_bind. *  02/21/89    mcmemeny Performance enhancements *  03/08/89    mcmenemy Change event handling algorithmn *  03/09/89    mcmenemy Add address generation to t_bind + mapping errors *                       returns to match verification spec. *  03/10/89    mcmenemy Put update check code back into t_close *  03/10/89    mcmenemy In t_snddis make sure call is valid before checking *                       call->sequence *  03/13/89    mcmenemy In t_snddis call XTIABORT setsockopt even in *                       T_DATAXFER state (instead of shutdown - which *                       would generate a T_ORDREL event. *  03/15/89    mcmenemy Change handling of error return for *                       TNOTSUPPORT/TBADDATA *  04/04/89    mcmenemy Fix t_unbind , make setsockopt call to unbind(zero) *                       pertinent fields without deleting control blocks. *			 This will allow for t_bind()-t-unbind() loops to work. *                       Place event enabling where endpoint becomes active *                       (ie. t_bind()) *  04/05/89    mcmenemy If rcvcall is not used in t_connect, don't use it. *  04/24/89    mcmenemy Make t_sndrel conformance to spec. *  04/27/89    mcmenemy Check for NULL call parameter in t_snddis. *  04/27/89    mcmenemy Re-add PEEK flag in t_rcv to set/clear T_MORE flag *  05/02/89    mcmenemy LINT. *  05/10/89    mcmenemy Add additional event syncronization in t_look. *                       This feature may be turned off by XTI_UNEVENT. *  07/14/89    mcmenemy Fix XPG3 Conformance bugs *  09/12/89	Ron B.   Fix segmentation fault in t_rcv on MIPS. *  11/22/89	Ron B.   Retrieve any user data sent by the caller in the *			 t_listen call. *  02/23/90	Ron B.   Returns the responding protocol address to the user *			 in t_connect call. *  03/05/90	Ron B.	 Switch over to use new osi.h. *			 When checking the length of protocol address against *			 the maximum protocol address size in t_info table, *			 take "-1" and "-2" into account. *			 Rewrite how t_accept does the checking. *			 Change to use new socket option name. *  04/11/90	Ron B.	 Make sure that we don't linger on t_close for OSI. *  05/17/90	Ron B.	 Fix accept checking for TCP. *  08/08/90    gray     Do not set acceptmode, nor listen if CLTS in *                       t_bind(). Inititalise seq. no in t_listen(). *                       Allow auto-addr generation for OSI. (courtesy *                       Matt Thomas). *  11/06/90    gray     Misc bug fixes to prevent various user areas *                       being overwritten. Conformance fixes to most *                       functions. *  11/14/90    heather  Merge changes, including from 11/22/89 above,  *                       into ULTRIX source pool. * ************************************************************************//* * XTI Library: xti.c * * This module provides the transport layer programming interface defined * in the X/OPEN Portability Guide: Networking Services.  *//*LINTLIBRARY*/#define XTI 1#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <malloc.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/xti.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include "xti_lib.h"extern char *allocate_addr();extern char *allocate_opt();extern char *allocate_udata();extern void bcopy();extern void perror();extern void map_err_to_XTI();/* * macro */#define table(fd) ((*d_table.dcb)[fd]) /* define macro for dynamic table */#define MAX(x,y) ((x > y) ? x : y )/* *	T_ACCEPT - accept a connect request */int t_accept (fd, resfd, call)int	fd;             /* where the connection indication arrived */int	resfd;          /* where the connection is to be established */struct	t_call *call;{#ifdef XTINSP    struct accessdata_dn nsp_accessdata;#endif    int status;    int optl;    int old_state;    int chklen;			/* total length of accept_check structure */    struct xti_evtinfo evtinfo;    struct accept_check {	int resfd;	int seqnum;	union {	    struct sockaddr generic;#ifdef	XTIOSI	    struct sockaddr_osi osi;#endif	XTIOSI	} addr;		/* sockaddr_osi must be the last one in structure */    } *chk;    if (!(check_xtifd(fd))) {	t_errno = TBADF;	return(-1);    }    if (!(check_xtifd(resfd))) {	t_errno = TBADF;	return(-1);    }    /*     * Must make sure we have dynamic table built.     */    if (d_table.dcb == T_NULL) {	t_errno = TBADF;	return(-1);    }    old_state = table(fd).state;    if ( (check_XTI_state(fd, XTI_ACCEPT1) == -1) &&	 (check_XTI_state(fd, XTI_ACCEPT2) == -1) &&	 (check_XTI_state(fd, XTI_ACCEPT3) == -1) ) {	t_errno = TOUTSTATE;	return(-1);    }    if ( (fd != resfd) && (check_XTI_state(resfd ,XTI_LISTEN) == -1) ) {	t_errno = TOUTSTATE;	return(-1);    }    if ( (fd != resfd) && (table(resfd).state != T_IDLE)) { 	t_errno = TOUTSTATE;	return(-1);    }    if (table(fd).info.servtype != T_COTS && 	table(fd).info.servtype != T_COTS_ORD) {	t_errno = TNOTSUPPORT;	return(-1);    }    if (fd != resfd) {	if (table(resfd).info.servtype != T_COTS && 	    table(resfd).info.servtype != T_COTS_ORD) {	    t_errno = TNOTSUPPORT;	    return(-1);	}    }    /*     * do some up-front checking     */    if (call->sequence <= 0) {	t_errno = TBADSEQ;	return(-1);    }  /*   * If the user has received other indications on this endpoint and has   * not responded to them, DO NOT allow the user to accept a connection on   * the same endpoint   */  if ((resfd == fd) && (table(fd).cnt_outs_con_ind > 1)) {    t_errno = TBADF;    return(-1);  }  if (table(fd).info.addr != -1 && table(fd).info.addr != -2)    if (call->addr.len > table(fd).info.addr) {      t_errno = TBADADDR;      return(-1);    }  /*   * Determine the actual length of the accept_check since the addr portion   * can be variable length.   */  switch(table(fd).family) {    case AF_INET:      chklen = sizeof(struct accept_check);      break;#ifdef XTIOSI    case AF_OSI:      chklen = sizeof(struct accept_check) +	       ((struct sockaddr_osi *)call->addr.buf)->osi_length;      break;#endif XTIOSI#ifdef XTINSP    case AF_DECnet:      chklen = 0;		/* we don't yet support NSP */      break;#endif XTINSP  }  /*   * Get buffer to pass information to be checked to the kernel.   * Then, load the buffer with the information.  This buffer   * will be passed to the kernel for actual checking.   */  chk = (struct accept_check *)malloc(chklen);  chk->seqnum = call->sequence;  chk->resfd = resfd;  bcopy( call->addr.buf, (char *)&chk->addr.generic, (int)call->addr.len);  /*   * Check to see if any event pending.   */  status = xti_peek(fd, &evtinfo);  if (status == -1) {    free(chk);    return(-1);  }  if (evtinfo.evtarray[ffs(T_LISTEN)] ||      evtinfo.evtarray[ffs(T_DISCONNECT)]) {    free(chk);    t_errno = TLOOK;    return(-1);  }    /*   * Send user data (if any)    */    if (call->udata.len > 0) {    if (table(resfd).info.connect == T_NOTSUPPORTED) {      t_errno = TBADDATA;      return(-1);    }    if (call->udata.len > (table(resfd).info.connect)) {      t_errno = TBADDATA;      return(-1);    }          switch(table(fd).family) {        case AF_INET:      break;#ifdef XTIOSI    case AF_OSI:      {	char *usrdat;	int usrdatlen = table(resfd).info.connect;	usrdat = (char *)malloc(usrdatlen);	if (usrdat == NULL) {	  t_errno = TSYSERR;	  errno = ENOBUFS;	  return(-1);	}	bzero(usrdat, usrdatlen);	bcopy(call->udata.buf, usrdat, call->udata.len);	status = setsockopt(resfd, OSIPROTO_COTS, TOPT_OPTCONDATA, 			    usrdat, call->udata.len);	free(usrdat);	if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  return(-1);	}	break;      }#endif#ifdef XTINSP    case AF_DECnet:            optl = call->udata.len;      status = setsockopt(resfd, DNPROTO_NSP, DSO_CONDATA, 			  call->udata.buf,			  optl );      if (status == -1) {	map_err_to_XTI(errno,&t_errno);	return(-1);      }      break;#endif    };  }  /*   * Send option data (if any)    */  if (call->opt.len > 0) {        if (table(fd).info.options == T_NOTSUPPORTED) {      t_errno = TNOTSUPPORT;      return(-1);    }    if (call->opt.len > table(fd).info.options) {      t_errno = TBADOPT;      return(-1);    }    switch(table(fd).family) {#ifdef XTIOSI    case AF_OSI:      { 	int tmp_len;	tmp_len = call->opt.len;	status = setsockopt(resfd, OSIPROTO_COTS, TOPT_XTICONOPTS,			    call->opt.buf,			    tmp_len );	  	if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  if (t_errno == TNOTSUPPORT) t_errno = TBADOPT; /* re-map */	  return(-1);	}      }      break;#endif    case AF_INET:      if (table(fd).xti_proto == IPPROTO_TCP) {	int tmp_len;	tmp_len = call->opt.len;	status = setsockopt(resfd, IPPROTO_TCP, TCP_CONOPT,			    call->opt.buf,			    tmp_len );	  	if (status == -1) {	  map_err_to_XTI(errno,&t_errno);	  if (t_errno == TNOTSUPPORT) t_errno = TBADOPT; /* re-map */	  return(-1);	}      }      break;#ifdef XTINSP    case AF_DECnet:            bcopy(call->opt.buf,(char *) &nsp_accessdata, call->opt.len);      optl = sizeof(struct accessdata_dn);      status = setsockopt(resfd, DNPROTO_NSP, DSO_CONACCESS, 			  (char *) &nsp_accessdata, 			  optl );            if (status == -1) {	map_err_to_XTI(errno,&t_errno);	return(-1);      }      break;#endif    };  }  /*   * deferred accept   */  status = setsockopt(fd, SOL_SOCKET, SO_XTIACCEPTCHK, (char *)chk, chklen);  if (status < 0) {    if (errno == EINVAL) { /* special case */      free(chk);      t_errno = TBADSEQ;      return(-1);    }    if (errno == EADDRNOTAVAIL ||	errno == EPROTONOSUPPORT) { /* special case */      free(chk);      t_errno = TBADADDR;      return(-1);    }    map_err_to_XTI(errno,&t_errno);    free(chk);    return(-1);  }  free(chk);  status = setsockopt(resfd, SOL_SOCKET, SO_XTISYNC, (char *) 0, 0);  if (status < 0) {    map_err_to_XTI(errno,&t_errno);    return(-1);  }  /*   * Accept the connection   */  switch(table(fd).family) {#ifdef XTIOSI  case AF_OSI:    status = setsockopt(resfd, OSIPROTO_COTS, TOPT_ACCEPT, (char *)0, 0);    if (status == -1) {      map_err_to_XTI(errno,&t_errno);      return(-1);    }    break;#endif  case AF_INET:    switch(table(fd).xti_proto) {        case IPPROTO_TCP:          status = setsockopt(resfd, IPPROTO_TCP, TCP_CONACCEPT, (char *) 0,0);          if (status < 0) {	t_errno = TSYSERR;	return(-1);      }      break;    default:      break;    };    break;#ifdef XTINSP  case AF_DECnet:    status = setsockopt(resfd, DNPROTO_NSP, DSO_CONACCEPT, (char *) 0, 0);    if (status == -1) {      map_err_to_XTI(errno,&t_errno);      return(-1);    }    break;#endif  default:    break;    };  /*   * re-load new states.   */  if (resfd != fd) {    old_state = t_getstate(fd); /* re-get new state */    (void) t_getstate(resfd);  }	      /*   *	Update XTI state tables   *   */  if ( (table(fd).cnt_outs_con_ind == 1) && (fd == resfd)) {    table(fd).event = XTI_ACCEPT1;   /* T_ACCEPT successful */    if (update_XTI_state(fd, resfd, old_state) == -1) {      t_errno = TOUTSTATE;      return(-1);    }  }  else     if ( (table(fd).cnt_outs_con_ind == 1) && (fd != resfd)) {      if (table(resfd).active_flag != 1) { 	t_errno = TOUTSTATE;	return(-1);      }	      /*       *	Update XTI state tables       *       */      table(fd).event = XTI_ACCEPT2;   /* T_ACCEPT successful */      if (update_XTI_state(fd, resfd, old_state) == -1) {	t_errno = TOUTSTATE;	return(-1);      }    }    else       /*       *	Update XTI state tables       *       */      /*       * This case impiles that fd != resfd       */      if (table(fd).cnt_outs_con_ind > 1) {		table(fd).event = XTI_ACCEPT3;   /* T_ACCEPT successful */	if (update_XTI_state(fd, resfd, old_state) == -1) {	  t_errno = TOUTSTATE;	  return(-1);	}      }  return (0);}/* * 	T_ALLOC - allocate a library structure (optional) */char   *t_alloc (fd, struct_type, fields)int fd;int struct_type;int fields;{  char *tmp_ptr = T_NULL;  char *tmp_addr = T_NULL;  char *tmp_opt = T_NULL;  char *tmp_udata = T_NULL;  int size;    if (!(check_xtifd(fd))) {    t_errno = TBADF;    return(T_NULL);  }  switch(struct_type) {      case T_BIND_STR:    tmp_ptr = (char *)malloc(sizeof(struct t_bind));        if (tmp_ptr == T_NULL) {      t_errno = TSYSERR;      errno = ENOBUFS;      return(T_NULL);    }    if (fields & T_ADDR) { /* ADDRESS */      if (table(fd).info.addr == -1) {		/* can't allocate infinity */	free(tmp_ptr);	t_errno = TSYSERR;	errno = EINVAL;	return(T_NULL);      }      tmp_addr = allocate_addr(struct_type, tmp_ptr, tmp_opt, tmp_udata,			       (int) table(fd).info.addr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -