📄 user.c
字号:
numbytes = (wind->size - wind->contain);
}
if (numbytes <= 0)
{
/* Check to see if a window probe is needed. A probe is only needed if
the foreign port has advertised a window of 0 and there is no
unacknowledged data. */
if ( (wind->size == 0) && (wind->nxt == wind->ack) )
{
if ((sent_by_wp=windowprobe(prt, nbytes, buffer)) == NU_NOT_ESTAB)
{
*status = NU_NOT_CONNECTED;
return(0);
}
/* Advance the buffer pointer beyond the data that has already been
sent. */
buffer += sent_by_wp;
numbytes = nbytes - sent_by_wp;
if (numbytes > (wind->size - wind->contain))
numbytes = wind->size - wind->contain;
}
else
{
*status = NU_WINDOW_FULL;
return(0);
}
}
/* Are there any packets that contain data but have not yet been sent.
Should never be more than one of these. */
if (wind->nextPacket != NU_NULL)
{
/* How much data can be copied into this partially filled buffer. */
if(numbytes > (int32)(MAX_SEGMENT_LEN - wind->nextPacket->data_len))
bytes_to_move = MAX_SEGMENT_LEN - wind->nextPacket->data_len;
else
bytes_to_move = numbytes;
/* Move the data into the buffer. */
memcpy((void *)(wind->nextPacket->data_ptr +
wind->nextPacket->data_len),
(const void *)buffer, bytes_to_move);
/* Update various conters and statistics. */
wind->nextPacket->data_len += (uint16)bytes_to_move;
prt->out.contain += (uint16)bytes_to_move;
nsent += (uint16)bytes_to_move;
numbytes -= bytes_to_move;
buffer += bytes_to_move;
}
bytes_to_move = MAX_SEGMENT_LEN;
while (numbytes > 0)
{
/* If there is not enough data left to fill a complete buffer,
update bytes_to_move with the number of bytes left. */
if (numbytes <= MAX_SEGMENT_LEN)
bytes_to_move = numbytes;
/* Check for ODH enabled. */
if (prt->odh_flag & NU_ODH_TRANSMIT)
{
/* If ODH is already enabled then simply derive the pointer to the
beginnig of the packet buffer. */
buf_ptr = (BUFFER *)(buffer - sizeof(DLAYER)
- sizeof(IPLAYER)
- sizeof(TCPLAYER)
- PQ_HEADER_SIZE);
/* Set up the next packet pointer. */
wind->nextPacket = buf_ptr;
}
else
{
/* Allocate a buffer */
buf_ptr = allocate_buffer(prt);
/* If no buffers available then return. */
if (buf_ptr == NU_NULL)
{
*status = NU_NO_BUFFERS;
numbytes = 0;
continue;
}
/* Point the data pointer at an offset into the buffer large
enough to leave room for the header information. */
buf_ptr->data_ptr = buf_ptr->packet + (sizeof(DLAYER) +
sizeof(IPLAYER) +
sizeof(TCPLAYER));
/* move the data into the packet buffer */
memcpy((void *)buf_ptr->data_ptr, (const void *)buffer,
bytes_to_move);
if(wind->nextPacket == NU_NULL)
wind->nextPacket = buf_ptr;
}
/* Initialize the data length of this buffer. */
buf_ptr->data_len = (uint16)bytes_to_move;
buf_ptr->option_len = 0;
/* Update the amount of data in this port. */
prt->out.contain += (uint16)bytes_to_move;
/* Update the number of packets in this port. */
prt->out.num_packets++;
/* Increment the number of bytes we have sent so far. */
nsent += (uint16)bytes_to_move;
/* Decrease the amount of data left before the caller's request has
* been filled. */
numbytes -= bytes_to_move;
/* Move the location from which we are copying forward. */
buffer += bytes_to_move;
}
/* Now that the data has been broken up into packets, send it. If some data
was sent and there was a timer event set to transmit data, then clear the
event. The data that the event was intended for has just been sent. */
if ( (netsend(prt) > 0) && (prt->xmitFlag) )
{
Stimerunset (CONCLASS, CONTX, prt->pindex, (int32)1);
prt->xmitFlag = NU_CLEAR;
}
/* There is some untransmitted data, set up a timer to make sure that it
gets transmitted. */
if(wind->nextPacket != NU_NULL)
{
prt->xmitFlag = NU_SET;
Stimerset(CONCLASS, CONTX, prt->pindex, SWSOVERRIDE, (int32)0);
}
/* If the other side has sent a FIN then indicate that the connection is
closing. */
if (prt->state == SCWAIT)
*status = NU_CLOSING;
return((int16)(nsent+sent_by_wp));
} /* end netwrite */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netqlen(int16) */
/* */
/* DESCRIPTION */
/* */
/* Returns the number of bytes waiting to be read from the incoming */
/* queue or<0 if error. */
/* */
/* CALLED BY */
/* */
/* CALLS */
/* */
/* */
/*************************************************************************/
int16 netqlen(int16 pnum)
{
if(portlist[pnum]==NU_NULL)
return(-2);
return((int16)portlist[pnum]->in.contain);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netroom(int16) */
/* */
/* DESCRIPTION */
/* */
/* Returns the number of bytes left in the output buffer for port */
/* *pnum*. Returns <0 if error occurs. */
/* */
/* CALLED BY */
/* */
/* CALLS */
/* */
/* */
/*************************************************************************/
int16 netroom(int16 pnum)
{
if(portlist[pnum]==NU_NULL || portlist[pnum]->state!=SEST)
return(-2);
return((int16)(WINDOWSIZE-portlist[pnum]->out.contain));
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netsetip(unsigned char *) */
/* */
/* DESCRIPTION */
/* */
/* Set a new ip number. This goes through and changes all sorts of ip */
/* numbers. This routine assumes that there are currently NO open */
/* tcp connections. */
/* */
/* CALLED BY */
/* parse_bootpacket */
/* bootp */
/* Snetinit */
/* */
/* CALLS */
/* */
/* */
/*************************************************************************/
void netsetip(unsigned char *st)
{
/*
* change all dependent locations relating to the IP number
* don't worry about open connections, they must be closed by higher
* layer
*/
/* main ip number */
memcpy ((void *)nnipnum, (const void *)st, 4);
/* arp */
memcpy ((void *)arp.spa, (const void *)nnipnum, 4);
/* ip source */
memcpy ((void *)blankip.i.ipsource, (const void *)nnipnum, 4);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netgetip(unsigned char *) */
/* */
/* DESCRIPTION */
/* */
/* Sets *st* to the current up number */
/* */
/* CALLED BY */
/* Snetinit */
/* */
/* CALLS */
/* */
/* */
/*************************************************************************/
void netgetip(unsigned char *st)
{
memcpy ((void *)st, (const void *)nnipnum, 4);
}
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netsetbroad(unsigned char *) */
/* */
/* DESCRIPTION */
/* */
/* Set the network broadcast IP address. */
/* */
/* CALLED BY */
/* Snetinit */
/* */
/* CALLS */
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -