コード例 #1
0
ファイル: tcp.c プロジェクト: YTakami/makecontroller
/**
 * Closes the connection held by the PCB.
 *
 */
err_t
tcp_close(struct tcp_pcb *pcb)
{
  err_t err;

#if TCP_DEBUG
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in state "));
  tcp_debug_print_state(pcb->state);
  LWIP_DEBUGF(TCP_DEBUG, ("\n"));
#endif /* TCP_DEBUG */
  switch (pcb->state) {
  case CLOSED:
    /* Closing a pcb in the CLOSED state might seem erroneous,
     * however, it is in this state once allocated and as yet unused
     * and the user needs some way to free it should the need arise.
     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
     * or for a pcb that has been used and then entered the CLOSED state 
     * is erroneous, but this should never happen as the pcb has in those cases
     * been freed, and so any remaining handles are bogus. */
    err = ERR_OK;
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    break;
  case LISTEN:
    err = ERR_OK;
    tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
    pcb = NULL;
    break;
  case SYN_SENT:
    err = ERR_OK;
    tcp_pcb_remove(&tcp_active_pcbs, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    break;
  case SYN_RCVD:
  case ESTABLISHED:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      pcb->state = FIN_WAIT_1;
    }
    break;
  case CLOSE_WAIT:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      pcb->state = LAST_ACK;
    }
    break;
  default:
    /* Has already been closed, do nothing. */
    err = ERR_OK;
    pcb = NULL;
    break;
  }

  if (pcb != NULL && err == ERR_OK) {
    err = tcp_output(pcb);
  }
  return err;
}
コード例 #2
0
ファイル: tcp.c プロジェクト: dafyddcrosby/L4OS
/*-----------------------------------------------------------------------------------*/
err_t
tcp_close(struct tcp_pcb *pcb)
{
  err_t err;

#if TCP_DEBUG
  DEBUGF(TCP_DEBUG, ("tcp_close: closing in state "));
  tcp_debug_print_state(pcb->state);
  DEBUGF(TCP_DEBUG, ("\n"));
#endif /* TCP_DEBUG */
  switch(pcb->state) {
  case LISTEN:
    err = ERR_OK;
    tcp_pcb_remove(TCP_LIST_LISTEN, pcb);
    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
    pcb = NULL;
    break;
  case SYN_SENT:
    err = ERR_OK;
    tcp_pcb_remove(TCP_LIST_ACTIVE, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    break;
  case SYN_RCVD:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if(err == ERR_OK) {
      pcb->state = FIN_WAIT_1;
    }
    break;
  case ESTABLISHED:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if(err == ERR_OK) {
      pcb->state = FIN_WAIT_1;
    }
    break;
  case CLOSE_WAIT:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if(err == ERR_OK) {
      pcb->state = LAST_ACK;
    }
    break;
  default:
    /* Has already been closed, do nothing. */
    err = ERR_OK;
    pcb = NULL;
    break;
  }

  if(pcb != NULL && err == ERR_OK) {
    err = tcp_output(pcb);
  }
  return err;
}
コード例 #3
0
ファイル: tcp.c プロジェクト: Minjunhao/RKB-DM8100
/**
 * Closes the connection held by the PCB.
 *
 * Listening pcbs are freed and may not be referenced any more.
 * Connection pcbs are freed if not yet connected and may not be referenced
 * any more. If a connection is established (at least SYN received or in
 * a closing state), the connection is closed, and put in a closing state.
 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
 * unsafe to reference it.
 *
 * @param pcb the tcp_pcb to close
 * @return ERR_OK if connection has been closed
 *         another err_t if closing failed and pcb is not freed
 */
err_t
tcp_close(struct tcp_pcb *pcb)
{
  err_t err;

#if TCP_DEBUG
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
  tcp_debug_print_state(pcb->state);
#endif /* TCP_DEBUG */

  switch (pcb->state) {
  case CLOSED:
    /* Closing a pcb in the CLOSED state might seem erroneous,
     * however, it is in this state once allocated and as yet unused
     * and the user needs some way to free it should the need arise.
     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
     * or for a pcb that has been used and then entered the CLOSED state 
     * is erroneous, but this should never happen as the pcb has in those cases
     * been freed, and so any remaining handles are bogus. */
    err = ERR_OK;
    TCP_RMV(&tcp_bound_pcbs, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    break;
  case LISTEN:
    err = ERR_OK;
    tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
    pcb = NULL;
    break;
  case SYN_SENT:
    err = ERR_OK;
    tcp_pcb_remove(&tcp_active_pcbs, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    snmp_inc_tcpattemptfails();
    break;
  case SYN_RCVD:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      snmp_inc_tcpattemptfails();
      pcb->state = FIN_WAIT_1;
    }
    break;
  case ESTABLISHED:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      snmp_inc_tcpestabresets();
      pcb->state = FIN_WAIT_1;
    }
    break;
  case CLOSE_WAIT:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      snmp_inc_tcpestabresets();
      pcb->state = LAST_ACK;
    }
    break;
  default:
    /* Has already been closed, do nothing. */
    err = ERR_OK;
    pcb = NULL;
    break;
  }

  if (pcb != NULL && err == ERR_OK) {
    /* To ensure all data has been sent when tcp_close returns, we have
       to make sure tcp_output doesn't fail.
       Since we don't really have to ensure all data has been sent when tcp_close
       returns (unsent data is sent from tcp timer functions, also), we don't care
       for the return value of tcp_output for now. */
    /* @todo: When implementing SO_LINGER, this must be changed somehow:
       If SOF_LINGER is set, the data should be sent when tcp_close returns. */
    tcp_output(pcb);
  }
  return err;
}
コード例 #4
0
ファイル: tcp.c プロジェクト: imaginegit/wifisdk
/**
 * Closes the connection held by the PCB.
 *
 * Listening pcbs are freed and may not be referenced any more.
 * Connection pcbs are freed if not yet connected and may not be referenced
 * any more. If a connection is established (at least SYN received or in
 * a closing state), the connection is closed, and put in a closing state.
 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
 * unsafe to reference it.
 *
 * @param pcb the tcp_pcb to close
 * @return ERR_OK if connection has been closed
 *         another uint8 if closing failed and pcb is not freed
 */
uint8 tcp_close(TCP_PCB *pcb)
{
    uint8 err = ERR_OK;

	tcp_tick_ack_unable(pcb);//printf("pcb->timerackflag = 0\n");
    switch (pcb->state)
    {
        case CLOSED:
            /* Closing a pcb in the CLOSED state might seem erroneous,
             * however, it is in this state once allocated and as yet unused
             * and the user needs some way to free it should the need arise.
             * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
             * or for a pcb that has been used and then entered the CLOSED state
             * is erroneous, but this should never happen as the pcb has in those cases
             * been freed, and so any remaining handles are bogus. */
            pcb->pcb_close(TCP_CLOSED);//Http_Check_Tcp_State
            memset(pcb, 0, sizeof(pcb));
            pcb = NULL;
            break;

        case SYN_SENT:
            tcp_pcb_remove_nolist(pcb);
            if (pcb->unacked != NULL)
            {
                tcp_segs_free(pcb->unacked);
    			pcb->unacked = NULL;
            }
            if (pcb->unsent != NULL)
            {
                tcp_segs_free(pcb->unsent);
    			pcb->unsent = NULL;
            }
            pcb->pcb_close(TCP_CLOSED);//Http_Check_Tcp_State
            memset(pcb, 0, sizeof(pcb));
            pcb = NULL;
            break;

        case ESTABLISHED:
            err = tcp_send_ctrl(pcb, TCP_FIN);
            if (err == ERR_OK)
            {
             	pcb->state = FIN_WAIT_1;
            }
            break;

        case CLOSE_WAIT:
            err = tcp_send_ctrl(pcb, TCP_FIN);
            if (err == ERR_OK) 
			{
	            pcb->state = LAST_ACK;
            }
            break;

        default:
            /* Has already been closed, do nothing. */
            pcb = NULL;
            break;
    }

    if (pcb != NULL && err == ERR_OK)
    {
        /* To ensure all data has been sent when tcp_close returns, we have
           to make sure tcp_output doesn't fail.
           Since we don't really have to ensure all data has been sent when tcp_close
           returns (unsent data is sent from tcp timer functions, also), we don't care
           for the return value of tcp_output for now. */
        /* @todo: When implementing SO_LINGER, this must be changed somehow:
           If SOF_LINGER is set, the data should be sent when tcp_close returns. */
        tcp_output(pcb);
    }
    return err;
}
コード例 #5
0
ファイル: tcp.c プロジェクト: sdwuyawen/lwip_V1.3.2
/**
 * Closes the connection held by the PCB.
 *
 * Listening pcbs are freed and may not be referenced any more.
 * Connection pcbs are freed if not yet connected and may not be referenced
 * any more. If a connection is established (at least SYN received or in
 * a closing state), the connection is closed, and put in a closing state.
 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore
 * unsafe to reference it.
 *
 * @param pcb the tcp_pcb to close
 * @return ERR_OK if connection has been closed
 *         another err_t if closing failed and pcb is not freed
 */
err_t
tcp_close(struct tcp_pcb *pcb)
{
  err_t err;

#if TCP_DEBUG
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
  tcp_debug_print_state(pcb->state);
#endif /* TCP_DEBUG */

  switch (pcb->state) {
	/* 若TCP在CLOSE状态,即tcp_new()之后从未使用过 */
  case CLOSED:
    /* Closing a pcb in the CLOSED state might seem erroneous,
     * however, it is in this state once allocated and as yet unused
     * and the user needs some way to free it should the need arise.
     * Calling tcp_close() with a pcb that has already been closed, (i.e. twice)
     * or for a pcb that has been used and then entered the CLOSED state 
     * is erroneous, but this should never happen as the pcb has in those cases
     * been freed, and so any remaining handles are bogus. */
    err = ERR_OK;
		/* 从tcp_bound_pcbs链表上删除(如果已经调用tcp_bind()的话) */
    TCP_RMV(&tcp_bound_pcbs, pcb);
		/* 释放TCP控制所占内存 */
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    break;
  case LISTEN:
    err = ERR_OK;
		/* 从LISTEN链表上删除,并发送可能存在的delayed ACKs */
    tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
		/* 释放LISTEN类型的TCP控制块 */
    memp_free(MEMP_TCP_PCB_LISTEN, pcb);
    pcb = NULL;
    break;
  case SYN_SENT:
    err = ERR_OK;
    tcp_pcb_remove(&tcp_active_pcbs, pcb);
    memp_free(MEMP_TCP_PCB, pcb);
    pcb = NULL;
    snmp_inc_tcpattemptfails();
    break;
  case SYN_RCVD:
		/* 构造FIN报文,主动关闭 */
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      snmp_inc_tcpattemptfails();
			/* 进入FIN_WAIT_1状态 */
      pcb->state = FIN_WAIT_1;
    }
    break;
  case ESTABLISHED:
		/* 构造FIN报文,主动关闭 */
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      snmp_inc_tcpestabresets();
			/* 进入FIN_WAIT_1状态 */
      pcb->state = FIN_WAIT_1;
    }
    break;
	/* 被动关闭,收到对方的FIN后,构造FIN关闭另一个方向传输 */
  case CLOSE_WAIT:
    err = tcp_send_ctrl(pcb, TCP_FIN);
    if (err == ERR_OK) {
      snmp_inc_tcpestabresets();
			/* 进入LAST_ACK状态 */
      pcb->state = LAST_ACK;
    }
    break;
	/* 其他状态,用TCP定时器函数实现 */
  default:
    /* Has already been closed, do nothing. */
    err = ERR_OK;
    pcb = NULL;
    break;
  }

	/* 发送TCP控制块中剩余的报文段,包括FIN报文	*/
  if (pcb != NULL && err == ERR_OK) {
    /* To ensure all data has been sent when tcp_close returns, we have
       to make sure tcp_output doesn't fail.
       Since we don't really have to ensure all data has been sent when tcp_close
       returns (unsent data is sent from tcp timer functions, also), we don't care
       for the return value of tcp_output for now. */
    /* @todo: When implementing SO_LINGER, this must be changed somehow:
       If SOF_LINGER is set, the data should be sent when tcp_close returns. */
    tcp_output(pcb);
  }
  return err;
}