📄 xti.c
字号:
*/ table(fd).info = tmp_info; /* save structure */ table(fd).family = c->x_af; /* address family */ table(fd).xti_proto = c->x_protocol; /* protocol number */ } else { t_errno = TBADNAME; return(-1); } /* * Update XTI state tables * */ table(fd).active_flag = 1; /* have an active descriptor */ table(fd).state = XTI_UNINIT; /* default state */ table(fd).event = XTI_OPENED; /* T_OPEN successful */ old_state = table(fd).state; if (update_XTI_state(fd, -1, old_state) == -1) { t_errno = TOUTSTATE; return(-1); } return (fd); }/* * T_OPTMGMT - manage options for a transport endpoint (optional) */int t_optmgmt (fd, req, ret)int fd;struct t_optmgmt *req;struct t_optmgmt *ret;{ int status; int old_state; if (!(check_xtifd(fd))) { t_errno = TBADF; return(-1); } if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */ t_errno = TBADF; return(-1); } old_state = table(fd).state; if (check_XTI_state(fd, XTI_IDLE) == -1) { t_errno = TOUTSTATE; return(-1); } if (req != T_NULL && ret != T_NULL) { switch (req->flags) { case T_NEGOTIATE: { int tmp_len; if ( (int) req->opt.len <= 0) { t_errno = TBADOPT; return(-1); } else if (req->opt.buf == T_NULL) { t_errno = TSYSERR; errno = EFAULT; return(-1); } if ( (int) ret->opt.maxlen <= 0) { t_errno = TBUFOVFLW; return(-1); } else if (ret->opt.buf == T_NULL) { t_errno = TSYSERR; errno = EFAULT; return(-1); } switch (table(fd).family) {#ifdef XTIOSI case AF_OSI: tmp_len = req->opt.len; status = setsockopt(fd, OSIPROTO_COTS, TOPT_XTINEGQOS, req->opt.buf, tmp_len ); ret->opt.len = tmp_len; if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } tmp_len = ret->opt.maxlen; status = getsockopt(fd, OSIPROTO_COTS, TOPT_XTINEGQOS, ret->opt.buf, &tmp_len ); ret->opt.len = tmp_len; if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } break;#endif case AF_INET: if (table(fd).xti_proto == IPPROTO_TCP) { tmp_len = req->opt.len; status = setsockopt(fd, IPPROTO_TCP, TCP_NEGQOS, req->opt.buf, tmp_len ); ret->opt.len = tmp_len; if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } tmp_len = ret->opt.maxlen; status = getsockopt(fd, IPPROTO_TCP, TCP_NEGQOS, ret->opt.buf, &tmp_len ); ret->opt.len = tmp_len; if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } } /* if TCP */ break; default: t_errno = TNOTSUPPORT; return(-1); }; /* end of switch */ ret->flags = 0; break; } break; case T_CHECK: { int tmp_len; if ( (int) req->opt.len <= 0) { t_errno = TBADOPT; return(-1); } if (req->opt.buf == T_NULL) { t_errno = TSYSERR; errno = EFAULT; return(-1); } switch (table(fd).family) {#ifdef XTIOSI case AF_OSI: tmp_len = req->opt.len; status = setsockopt(fd, OSIPROTO_COTS, TOPT_XTICHKQOS, req->opt.buf, tmp_len ); if (status == -1) { ret->flags = T_FAILURE; map_err_to_XTI(errno,&t_errno); return(-1); } break;#endif case AF_INET: if (table(fd).xti_proto == IPPROTO_TCP) { tmp_len = req->opt.len; status = setsockopt(fd, IPPROTO_TCP, TCP_CHKQOS, req->opt.buf, tmp_len ); if (status == -1) { ret->flags = T_FAILURE; map_err_to_XTI(errno,&t_errno); return(-1); } } break; default: t_errno = TNOTSUPPORT; return(-1); }; /* end of switch */ ret->flags = T_SUCCESS; } break; case T_DEFAULT: { int tmp_len; if (req->opt.len != 0) { t_errno = TBADOPT; return(-1); } if ( (int) ret->opt.maxlen <= 0) { t_errno = TBUFOVFLW; return(-1); } else if (ret->opt.buf == T_NULL) { t_errno = TSYSERR; errno = EFAULT; return(-1); } switch (table(fd).family) {#ifdef XTIOSI case AF_OSI: tmp_len = ret->opt.maxlen; status = getsockopt(fd, OSIPROTO_COTS, TOPT_XTIDFLTQOS, ret->opt.buf, &tmp_len ); ret->opt.len = tmp_len; if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } break;#endif case AF_INET: if (table(fd).xti_proto == IPPROTO_TCP) { tmp_len = ret->opt.maxlen; status = getsockopt(fd, IPPROTO_TCP, TCP_DFLTQOS, ret->opt.buf, &tmp_len ); ret->opt.len = tmp_len; if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } } break; default: t_errno = TNOTSUPPORT; return(-1); }; /* end of switch */ ret->flags = 0; } break; default: t_errno = TBADFLAG; return(-1); }; /* end of switch */ } else { t_errno = TSYSERR; errno = EFAULT; return(-1); } /* * Update XTI state tables * */ table(fd).event = XTI_OPTMGMT; if (update_XTI_state(fd, -1, old_state) == -1) { t_errno = TOUTSTATE; return(-1); } return(0);}/* * T_RCV - receive data or expedited data sent over a connection */int t_rcv (fd, buf, nbytes, flags)int fd;char *buf;unsigned nbytes;int *flags;{ int rbytes=0; /* actual #bytes received by transport provider */ int status; int old_state; char *tmp_buf = NULL; int peek_expd; int peek_normal; struct xti_evtinfo evtinfo; if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */ t_errno = TBADF; return(-1); } if (!(table(fd).active_flag)) { t_errno = TBADF; return(-1); } old_state = table(fd).state; if (check_XTI_state(fd, XTI_RCV) == -1) { 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 (flags == T_NULL) { t_errno = TSYSERR; errno = EINVAL; return(-1); }retry: *flags = 0; /* initalize flags */ status = xti_peek(fd, &evtinfo); if (status == -1) return(-1); /* SPECIAL logic: * * Do not return TLOOK error for T_DISCONNECT | T_ORDREL if we have * either T_EXDATA | T_DATA event. * In addition, we give precedence of T_EXDATA over T_DATA */ if ((evtinfo.evtarray[ffs(T_DISCONNECT)] || evtinfo.evtarray[ffs(T_ORDREL)]) && ( (!evtinfo.evtarray[ffs(T_DATA)]) && (!evtinfo.evtarray[ffs(T_EXDATA)]))) { t_errno = TLOOK; return(-1); } switch(table(fd).family) { case AF_INET: break; case AF_DECnet: break;#ifdef XTIOSI case AF_OSI: tmp_buf = (char *)malloc(nbytes+1); if (tmp_buf == T_NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(-1); } break;#endif }; peek_expd = evtinfo.evtarray[ffs(T_EXDATA)]; if (peek_expd != 0) { switch(table(fd).family) { case AF_INET: break; case AF_DECnet: break;#ifdef XTIOSI case AF_OSI: peek_expd = recv (fd, tmp_buf, (int) nbytes+1, MSG_OOB | MSG_PEEK); /* get count */ if (peek_expd <= nbytes) *flags &= ~T_MORE; else *flags |= T_MORE; break;#endif }; rbytes = recv (fd, buf, (int) nbytes, MSG_OOB); *flags |= T_EXPEDITED; } else { switch(table(fd).family) { case AF_INET: break; case AF_DECnet: break;#ifdef XTIOSI case AF_OSI: peek_normal = recv (fd, tmp_buf, (int) nbytes+1, MSG_PEEK); /* * If we get ENOTEMPTY error, then we got expedited data while * we were waiting. So, go back and try to get it. Otherwise, * we got normal data. */ if (peek_normal < 0 && errno == ENOTEMPTY) { if (tmp_buf) free(tmp_buf); goto retry; } if (peek_normal <= nbytes) *flags &= ~T_MORE; else *flags |= T_MORE; break;#endif }; rbytes = recv (fd, buf, (int) nbytes, 0); } if (tmp_buf) free(tmp_buf); if (rbytes < 0 && errno == ENOTEMPTY) goto retry; if (rbytes < 0) { map_err_to_XTI(errno,&t_errno); return (-1); } /* * Update XTI state tables * */ table(fd).event = XTI_RCV; if (table(fd).state != T_DATAXFER) { /* performance code */ if (update_XTI_state(fd, -1, old_state) == -1) { t_errno = TOUTSTATE; return(-1); } } return (rbytes);}/* * T_RCVCONNECT - receive the confirmation from a connect request */int t_rcvconnect (fd, call)int fd;struct t_call *call;{ int optl; int status; int status1; int old_state; int tmp_size; struct xti_evtinfo evtinfo; int buffer_overflow = 0; int tmp_len; if (!(check_xtifd(fd))) { t_errno = TBADF; return(-1); } if (d_table.dcb == T_NULL) { /* must make sure we have dynamic table built */ t_errno = TBADF; return(-1); } old_state = table(fd).state; if (check_XTI_state(fd, XTI_RCVCONNECT) == -1) { 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 ( (status = xti_peek(fd, &evtinfo)) == -1) return(-1); if (evtinfo.evtarray[ffs(T_DISCONNECT)]) { t_errno = TLOOK; return(-1); } if (evtinfo.evtarray[ffs(T_CONNECT)] == 0) { t_errno = TNODATA; return(-1); } else { /* * get rid of T_CONNECT event */ tmp_size = sizeof(status1); status1 = T_CONNECT; status = setsockopt(fd, SOL_SOCKET, SO_XTICLREVENT, (char *) &status1, tmp_size); if (status < 0) { map_err_to_XTI(errno, &t_errno); return(-1); } } if (call != T_NULL) { /* * Address information */ if (call->addr.maxlen > 0) { if (call->addr.maxlen < table(fd).info.addr) { buffer_overflow = 1; } if (!buffer_overflow) { /* * go to kernel to get sockname */ tmp_len = call->addr.maxlen; status = getsockname(fd, call->addr.buf, &tmp_len); if (status == -1) { map_err_to_XTI(errno,&t_errno); return(-1); } call->addr.len = tmp_len; } } /* * User data */ if (call->udata.maxlen > 0) { if (table(fd).info.connect == T_NOTSUPPORTED) { t_errno = TNOTSUPPORT; return(-1); } switch(table(fd).family) { case AF_INET: break;#ifdef XTIOSI case AF_OSI: { char *usrdat; int usrdatlen = table(fd).info.connect; usrdat = (char *)malloc(usrdatlen); if (usrdat == NULL) { t_errno = TSYSERR; errno = ENOBUFS; return(-1); } bzero(usrdat, usrdatlen); status = getsockopt(fd, OSIPROTO_COTS, TOPT_OPTCONDATA, usrdat, &usrdatlen); if (status == -1) { free(usrdat); map_err_to_XTI(errno,&t_errno); return(-1); } if (call->udata.maxlen < usrdatlen) { buffer_overflow = 1; } if (!buffer_overflow) { bcopy(usrdat, call->udata.buf, usrdatlen); call->udata.len = usrdat
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -