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

📄 ldp_session.c

📁 Linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) James R. Leu 2000 *  jleu@mindspring.com * *  This software is covered under the LGPL, for more *  info check out http://www.gnu.org/copyleft/lgpl.html */#include <stdlib.h>#include "ldp_struct.h"#include "ldp_outlabel.h"#include "ldp_session.h"#include "ldp_entity.h"#include "ldp_inlabel.h"#include "ldp_outlabel.h"#include "ldp_addr.h"#include "ldp_attr.h"#include "ldp_adj.h"#include "ldp_mesg.h"#include "ldp_buf.h"#include "ldp_inet_addr.h"#include "ldp_global.h"#include "ldp_state_machine.h"#include "ldp_label_rel_with.h"#include "ldp_label_request.h"#include "ldp_label_mapping.h"#include "mpls_refcnt.h"#include "mpls_assert.h"#include "mpls_mm_impl.h"#include "mpls_timer_impl.h"#include "mpls_socket_impl.h"#include "mpls_trace_impl.h"#include "mpls_ifmgr_impl.h"#include "mpls_policy_impl.h"#include "mpls_lock_impl.h"static uint32_t _ldp_session_next_index = 1;mpls_return_enum ldp_session_attempt_setup(ldp_global *g, ldp_session *s);mpls_return_enum ldp_session_backoff_stop(ldp_global * g, ldp_session * s);static void ldp_session_backoff_callback(mpls_timer_handle timer, void *extra,  mpls_cfg_handle handle){  ldp_session *s = (ldp_session *)extra;  ldp_global *g = (ldp_global*)handle;  LDP_ENTER(g->user_data, "ldp_session_backoff");  LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_TIMER,    "Session Backoff Timer fired: session(%s)\n", s->session_name);  mpls_lock_get(g->global_lock);  s->backoff_timer = 0;  if (s->oper_role == LDP_ACTIVE) {    if (ldp_session_attempt_setup(g, s) != MPLS_SUCCESS) {      s->backoff += g->backoff_step;      s->backoff_timer = timer;      mpls_timer_start(g->timer_handle, timer, MPLS_TIMER_ONESHOT);      LDP_EXIT(g->user_data, "ldp_session_backoff-error");      goto ldp_session_backoff_end;    }  } else if (s->oper_role == LDP_PASSIVE) {    /* this is a passive session that never received an init, kill it     * session current on the global list and the timer holds a refcnt.     * shutdown takes this session off of the global list, so when the     * timer refcnt is released the session will be deleted */    ldp_session_shutdown(g, s, MPLS_BOOL_TRUE);  } else {    MPLS_ASSERT(0);  }  mpls_timer_stop(g->timer_handle, timer);  mpls_timer_delete(g->timer_handle, timer);  MPLS_REFCNT_RELEASE(s, ldp_session_delete);ldp_session_backoff_end:  mpls_lock_release(g->global_lock);  LDP_EXIT(g->user_data, "ldp_session_backoff");}ldp_session *ldp_session_create(){  ldp_session *s = (ldp_session *) mpls_malloc(sizeof(ldp_session));  if (s) {    memset(s, 0, sizeof(ldp_session));    MPLS_REFCNT_INIT(s, 0);    MPLS_LIST_ELEM_INIT(s, _global);    MPLS_LIST_INIT(&s->outlabel_root, ldp_outlabel);    MPLS_LIST_INIT(&s->attr_root, ldp_attr);    MPLS_LIST_INIT(&s->adj_root, ldp_adj);    mpls_link_list_init(&s->inlabel_root);    mpls_link_list_init(&s->addr_root);    s->on_global = MPLS_BOOL_FALSE;    s->tx_buffer = ldp_buf_create(MPLS_PDUMAXLEN);    s->tx_message = ldp_mesg_create();    s->index = _ldp_session_get_next_index();    s->oper_role = LDP_NONE;  }  return s;}mpls_return_enum ldp_session_attempt_setup(ldp_global *g, ldp_session *s) {  mpls_socket_handle socket = mpls_socket_create_tcp(g->socket_handle);  mpls_return_enum retval;  LDP_ENTER(g->user_data, "ldp_session_attempt_setup");  if (mpls_socket_handle_verify(g->socket_handle, socket) == MPLS_BOOL_FALSE) {    return MPLS_FAILURE;  }  if (mpls_socket_options(g->socket_handle, socket, MPLS_SOCKOP_NONBLOCK) ==    MPLS_FAILURE) {    goto ldp_session_attempt_setup_error;  }  retval = mpls_socket_tcp_connect(g->socket_handle, socket, &s->remote_dest);  switch (retval) {    case MPLS_NON_BLOCKING:      {	LDP_TRACE_OUT(g->user_data,	  "ldp_session_attempt_setup: MPLS_NON_BLOCKING\n");        mpls_socket_writelist_add(g->socket_handle, socket, (void *)s,          MPLS_SOCKET_TCP_CONNECT);        break;      }    case MPLS_SUCCESS:      {	LDP_TRACE_OUT(g->user_data,	  "ldp_session_attempt_setup: MPLS_SUCCESS\n");        if (ldp_state_machine(g, s, NULL, NULL, LDP_EVENT_CONNECT, NULL,            NULL) == MPLS_FAILURE) {          goto ldp_session_attempt_setup_error;        }        break;      }    default:      {	LDP_TRACE_OUT(g->user_data,	  "ldp_session_attempt_setup: MPLS_FAILURE\n");        goto ldp_session_attempt_setup_error;      }      break;  }  s->socket = socket;  LDP_EXIT(g->user_data, "ldp_session_attempt_setup");  return MPLS_SUCCESS;ldp_session_attempt_setup_error:  mpls_socket_close(g->socket_handle, socket);  LDP_EXIT(g->user_data, "ldp_session_attempt_setup");  return MPLS_FAILURE;}mpls_return_enum ldp_session_create_active(ldp_global * g, ldp_adj * a){  mpls_return_enum retval = MPLS_FAILURE;  mpls_inet_addr *addr = NULL;  ldp_session *s = NULL;  ldp_adj* ap;  MPLS_ASSERT(g && a && (!a->session));  LDP_ENTER(g->user_data, "ldp_session_create_active");  ap = MPLS_LIST_HEAD(&g->adj);  while (ap) {    if ((!mpls_inet_addr_compare(&ap->remote_lsr_address,      &a->remote_lsr_address)) &&      ap->remote_label_space == a->remote_label_space &&      a->index != ap->index && ap->session) {      ldp_adj_add_session(a, ap->session);      retval = MPLS_SUCCESS;      goto ldp_session_create_active;    }    ap = MPLS_LIST_NEXT(&g->adj, ap, _global);  }  if ((s = ldp_session_create())) {    if (a->remote_transport_address.type != MPLS_FAMILY_NONE) {      addr = &a->remote_transport_address;    } else {      addr = &a->remote_source_address;    }    _ldp_global_add_session(g, s);    ldp_adj_add_session(a, s);    s->state = LDP_STATE_NON_EXIST;    memcpy(&s->remote_dest.addr, addr, sizeof(mpls_inet_addr));    s->remote_dest.port = s->cfg_peer_tcp_port;    LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,      "ldp_session_create_active: (%d) changed to NON_EXIST\n", s->index);    if (ldp_session_attempt_setup(g, s) != MPLS_SUCCESS) {      /* go into backoff */      ldp_session_backoff_start(g, s);    }    retval = MPLS_SUCCESS;  }ldp_session_create_active:  LDP_EXIT(g->user_data, "ldp_session_create_active");  return retval;}ldp_session *ldp_session_create_passive(ldp_global * g,  mpls_socket_handle socket, mpls_dest * from){  ldp_session *s = NULL;  MPLS_ASSERT(g);  LDP_ENTER(g->user_data, "ldp_session_create_passive");  if ((s = ldp_session_create())) {    s->socket = socket;    s->state = LDP_STATE_NON_EXIST;    if (mpls_socket_options(g->socket_handle, socket, MPLS_SOCKOP_NONBLOCK) ==      MPLS_SUCCESS) {      LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,        "ldp_session_create_passive: (%d) changed to NON_EXIST\n", s->index);      _ldp_global_add_session(g, s);    } else {      ldp_session_delete(s);      s = NULL;    }  }  LDP_EXIT(g->user_data, "ldp_session_create_passive (%p)", s);  return s;}void ldp_session_delete(ldp_session * s){  LDP_PRINT(NULL, "session delete");  MPLS_REFCNT_ASSERT(s, 0);  mpls_free(s);}mpls_return_enum ldp_session_startup(ldp_global * g, ldp_session * s){  mpls_return_enum retval = MPLS_FAILURE;  ldp_addr *addr;  void (*callback) (mpls_timer_handle timer, void *extra, mpls_cfg_handle g);  MPLS_ASSERT(s && g && (s->oper_role != LDP_NONE));  LDP_ENTER(g->user_data, "ldp_session_startup");  /* when we make it to operational, get rid of any backoff timers */  ldp_session_backoff_stop(g, s);  s->state = LDP_STATE_OPERATIONAL;  s->oper_up = time(NULL);  LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,    "ldp_session_startup: (%d) changed to OPERATIONAL\n", s->index);  /*   * if configured to distribute addr messages walk the if table   * and send an addr message for each   */  if (g->send_address_messages) {    addr = MPLS_LIST_HEAD(&g->addr);    while (addr) {      /* only locally attached addrs will have a valid iff */      if (addr->iff) {        if (ldp_addr_send(g, s, &addr->address) != MPLS_SUCCESS)          goto ldp_session_startup_end;      }      addr = MPLS_LIST_NEXT(&g->addr, addr, _global);    }  }  /* depending on the mode, grab a pointer to the correct callback */  switch (s->oper_distribution_mode) {    case LDP_DISTRIBUTION_ONDEMAND:      callback = ldp_label_request_initial_callback;      break;    case LDP_DISTRIBUTION_UNSOLICITED:      callback = ldp_label_mapping_initial_callback;      break;    default:      MPLS_ASSERT(0);  }  /*   * create a timer which will go about "chunking" the initial   * set of requests or mappings   */  MPLS_REFCNT_HOLD(s);  s->initial_distribution_timer = mpls_timer_create(g->timer_handle,    MPLS_UNIT_SEC, LDP_REQUEST_CHUNK, (void *)s, g, callback);  if (mpls_timer_handle_verify(g->timer_handle,      s->initial_distribution_timer) == MPLS_BOOL_FALSE) {    MPLS_REFCNT_RELEASE(s, ldp_session_delete);    LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,      "ldp_session_startup: initial distrib error(%d)\n", s->index);    /* timer error, we might as well shutdown the session, it's usless */    s->shutdown_notif = LDP_NOTIF_INTERNAL_ERROR;    s->shutdown_fatal = MPLS_BOOL_TRUE;    retval = MPLS_FAILURE;  } else {    mpls_timer_start(g->timer_handle, s->initial_distribution_timer,      MPLS_TIMER_ONESHOT);    retval = MPLS_SUCCESS;  }ldp_session_startup_end:  LDP_EXIT(g->user_data, "ldp_session_startup");  return retval;}void ldp_session_shutdown(ldp_global * g, ldp_session * s, mpls_bool complete){  ldp_addr *a = NULL;  ldp_attr *attr = NULL;  ldp_attr *nattr = NULL;  ldp_adj* ap;  MPLS_ASSERT(s);  LDP_ENTER(g->user_data, "ldp_session_shutdown");  /*   * hold a refcount so this session doesn't disappear on us   * while cleaning up   */  MPLS_REFCNT_HOLD(s);  s->state = LDP_STATE_NONE;  LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_ALL, LDP_TRACE_FLAG_DEBUG,    "ldp_session_shutdown: (%d) changed to NONE\n", s->index);  /*   * kill the timers for the session   */  if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_recv_timer) ==    MPLS_BOOL_TRUE) {    mpls_timer_stop(g->timer_handle, s->keepalive_recv_timer);    mpls_timer_delete(g->timer_handle, s->keepalive_recv_timer);    MPLS_REFCNT_RELEASE(s, ldp_session_delete);    s->keepalive_recv_timer = (mpls_timer_handle) 0;  }  if (mpls_timer_handle_verify(g->timer_handle, s->keepalive_send_timer) ==    MPLS_BOOL_TRUE) {    mpls_timer_stop(g->timer_handle, s->keepalive_send_timer);    mpls_timer_delete(g->timer_handle, s->keepalive_send_timer);    MPLS_REFCNT_RELEASE(s, ldp_session_delete);    s->keepalive_send_timer = (mpls_timer_handle) 0;  }  if (mpls_timer_handle_verify(g->timer_handle,s->initial_distribution_timer) ==    MPLS_BOOL_TRUE) {

⌨️ 快捷键说明

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