📄 user.c
字号:
/* (called from Snetinit () ) */
/* */
/* Returns 0 on successful initialization. */
/* */
/* CALLED BY */
/* Snetinit */
/* */
/* CALLS */
/* */
/* dlayerinit */
/* protinit */
/* */
/*************************************************************************/
int16 netinit (void)
{
int16 ret;
/*
* Initializes all buffers and hardware for data link layer.
* Machine/board dependent.
*/
ret = dlayerinit ();
if (ret)
{
switch (ret)
{
case -10:
/* ERROR Need a function for opening board!!\n */
break;
default:
/* ERROR Board initialization failed!. Error code=%d\n",ret */
break;
} /* end switch */
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_RECOVERABLE,
__FILE__, __LINE__);
return (ret);
} /* end if */
/*
* initialize the template packets needed for transmission
*/
return (protinit ());
} /* netinit */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* windowprobe */
/* */
/* DESCRIPTION */
/* */
/* Time out for three seconds. Then if the window has not been updated*/
/* send a 1 byte packet(windowprobe). */
/* */
/* CALLED BY */
/* netwrite */
/* */
/* CALLS */
/* */
/* Stimerset */
/* NU_Current_Task_Pointer */
/* NU_Release_Semaphore */
/* NU_Suspend_Task */
/* NU_Obtain_Semaphore */
/* */
/* INPUTS */
/* prt Pointer to a port. */
/* nbytes The number of bytes in the buffer parameter. */
/* buffer Pointer to a data buffer. */
/* */
/* OUTPUTS */
/* */
/* The number of bytes that were sent in window probes. */
/* */
/* HISTORY */
/* NAME DATE REMARKS */
/* */
/* G. Johnson 04/13/95 Created initial version. */
/* Maiqi Qian 12/12/96 Modified windowprobe to probe forever. */
/* */
/*************************************************************************/
INT windowprobe(PORT *prt, uint16 nbytes, char *buffer)
{
uint16 nsent = 0;
BUFFER *buf_ptr;
/* Set the probe flag. */
prt->probeFlag = NU_SET;
prt->rto = MINRTO;
/* Set a timer event to resume this task. */
Stimerset(CONCLASS, WINPROBE, prt->pindex, PROBETIMEOUT, 0);
/* Probe the foreign host while he is advertising a window size of 0. */
while(prt->out.size == 0)
{
#ifdef PLUS
/* Preserve the the task pointer. */
prt->TXTask = NU_Current_Task_Pointer();
/* Allow other tasks to access the TCP/IP stack. */
NU_Release_Semaphore(&TCP_Resource);
/* Suspend this task. */
NU_Suspend_Task(prt->TXTask);
prt->TXTask = NU_NULL;
/* Grab the semaphore. */
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else /* RTX */
/* Preserve the the task pointer. */
prt->TXTask = NU_Current_Task_ID();
/* Allow other tasks to access the TCP/IP stack. */
NU_Release_Resource(TCP_Resource);
/* Suspend this task. */
NU_Stop(prt->TXTask);
prt->TXTask = -1;
/* Grab the semaphore. */
NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif
/* If this a close was initiated while suspension was in effect abort
the window probe. */
if (prt->state != SEST)
return(NU_NOT_ESTAB);
/* if the windowsize is still zero and no unacknowledged data has been
* sent and the buffer has untransmitted data, then send a window
* probe. We depend on the retransmit logic to resend the window probe
* until either the probe is acknowledged or the window is opened. */
if( (prt->out.size == 0) && (prt->out.contain == 0) && (nsent < nbytes))
{
/* Allocate a buffer to put the window probe packet into. */
buf_ptr = allocate_buffer(prt);
if (buf_ptr != NU_NULL)
{
/* 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, 1);
/* Initialize the data length of this buffer. */
buf_ptr->data_len = 1;
buf_ptr->option_len = 0;
/* Update the amount of data in this port. */
prt->out.contain++;
/* Update the number of packets in this port. */
prt->out.num_packets++;
/* Increment the number of bytes we have sent so far. */
nsent++;
/* Move the location from which we are copying forward. */
buffer++;
/* Send the completed Packet. */
tcp_xmit(prt, buf_ptr);
}
}
else if (prt->out.size > 0)
break;
/* Set a timer event to resume this task just before the retransmits
is about finishing. */
Stimerset(CONCLASS,WINPROBE,prt->pindex,prt->rto*(MAX_RETRANSMITS-1),0);
/* reset retransmits number, make the probing forever. MQ */
buf_ptr->retransmits = MAX_RETRANSMITS;
}
/* At this point if there is a packet on the outgoing packet list. Then
* that means the foreign host opened up his window without
* acknowledging the window probe. Since the probe contains the next byte
* expected by the foreign host, go ahead and retransmit it. Otherwise, an
* out of order packet situation will occur and it will take longer to fully
* recover from the 0 windowsize. */
if (prt->out.packet_list.head != NU_NULL)
{
/* Clear the timer that will retransmit the window probe. */
Stimerunset(CONCLASS, WINPROBE, prt->pindex, (int32)1);
tcp_retransmit(prt, prt->out.packet_list.head->seqnum);
}
/* Clear the probe flag. */
prt->probeFlag = NU_CLEAR;
return(nsent);
} /* end windowprobe */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netsend */
/* */
/* DESCRIPTION */
/* */
/* This function examines the ports outwindow and sends the data that */
/* is queued in the windows packet_list. All of the data may not be */
/* sent immediately. The decision to send data immediately or to hold */
/* off is based on the Nagle Algorithm (RFC 1122, page 98). */
/* */
/* CALLED BY */
/* netwrite */
/* */
/* CALLS */
/* */
/* tcp_xmit */
/* */
/* INPUTS */
/* prt Pointer to a port. */
/* */
/* OUTPUTS */
/* */
/* The number of bytes that were sent. */
/* */
/* HISTORY */
/* NAME DATE REMARKS */
/* */
/* G. Johnson 04/13/95 Created Initial version. */
/* */
/*************************************************************************/
uint16 netsend(PORT *prt)
{
uint16 nsent = 0;
WINDOW *wind;
wind = &prt->out;
// modified by ason. (always push!)
wind->push = TPUSH;
/* As long as there is are more packets available send them. */
while(wind->nextPacket != NU_NULL)
{
/* Check to see if the PUSH flag has been set (i.e., the Nagle Algorithm
has been disabled). If so send every packet immediately with the
push flag set. */
if(wind->push || (prt->odh_flag & NU_ODH_TRANSMIT) )
{
prt->tcpout.t.flags |= TPUSH;
/* Send the packet. */
tcp_xmit(prt, wind->nextPacket);
/* Update the number of data bytes sent so far. */
nsent += wind->nextPacket->data_len;
/* Point to the next packet. */
wind->nextPacket = (BUFFER *)wind->nextPacket->next;
}
/* Should the next packet be sent? This decision is based on the Nagle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -