struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr, int dtlsmode) { struct sockaddr dbgaddr; socklen_t dbgaddrl; int sockfd, replyfd; char sock_buf[SOCK_ADDR_BUFSIZE]; struct wtpman *wtpman; wtpman = malloc(sizeof(struct wtpman)); if (!wtpman) return 0; memset(wtpman, 0, sizeof(struct wtpman)); if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) { int port = sock_getport(&socklist[socklistindex].addr); replyfd = socklist_find_reply_socket(srcaddr, port); if (replyfd == -1) { cw_log(LOG_ERR, "Can't find reply socket for request from %s", sock_addr2str(srcaddr,sock_buf)); free(wtpman); return NULL; } } else { replyfd = socklist[socklistindex].sockfd; } sockfd = replyfd; /*//socklist[socklistindex].reply_sockfd;*/ dbgaddrl = sizeof(dbgaddr); getsockname(sockfd, &dbgaddr, &dbgaddrl); cw_dbg(DBG_INFO, "Creating wtpman on socket %d, %s:%d", sockfd, sock_addr2str(&dbgaddr,sock_buf), sock_getport(&dbgaddr)); wtpman->conn = conn_create(sockfd, srcaddr, 100); wtpman->conn->role = CW_ROLE_AC; wtpman->conn->data_sock = socklist[socklistindex].data_sockfd; sock_copyaddr(&wtpman->conn->data_addr, (struct sockaddr *) &wtpman->conn->addr); if (!wtpman->conn) { wtpman_destroy(wtpman); return NULL; } wtpman->conn->mods = conf_mods; wtpman->conn->strict_capwap = conf_strict_capwap; wtpman->conn->strict_hdr = conf_strict_headers; /* // wtpman->conn->radios = mbag_i_create(); // wtpman->conn->radios_upd = mbag_i_create(); // wtpman->conn->local = ac_config; //wtpman->conn->capwap_mode=0; //CW_MODE_STD; //CISCO; // wtpman->conn->capwap_mode = CW_MODE_CISCO; //wtpman->conn->strict_capwap_hdr=0; */ wtpman->conn->local_cfg = cw_ktv_create(); wtpman->conn->global_cfg = actube_global_cfg; wtpman->conn->local_cfg = actube_global_cfg; /* when created caused by a packet in DTLS mode, we try * to find out the modules to load, for detected connection * from discovery request */ if (dtlsmode){ int rc; struct cw_Mod *cmod, *bmod; rc = discovery_cache_get(discovery_cache,srcaddr,&cmod,&bmod); if (rc){ cw_dbg(DBG_INFO, "Initializing with mod %s %s",cmod->name,bmod->name); wtpman->conn->msgset = cw_mod_get_msg_set(wtpman->conn,cmod,bmod); wtpman->conn->detected=1; cmod->setup_cfg(wtpman->conn); } } return wtpman; }
/** * Create a conn object * @param sock a socket * @param addr the address associated * @param qsize size of packet queue * @return A pointer to the created object * This function creates a conn obnject with queueing functionality * for asynchronous operation. * To create a conn object without queue functionallity use #conn_create_noq. */ struct conn * conn_create(int sock, struct sockaddr * addr, int qsize) { struct conn * conn; conn = malloc(sizeof (struct conn)); if (!conn) return NULL; conn_init(conn); conn->sock=sock; if (addr) sock_copyaddr(&conn->addr,addr); conn->fragman = fragman_create(); if (conn->fragman==NULL){ conn_destroy(conn); return NULL; } conn->qsize=qsize; if (qsize != 0){ if (!(conn->q=malloc( sizeof(uint8_t *) * qsize))){ conn_destroy(conn); return NULL; } conn->qrpos=-1; if (sem_init(&conn->q_sem,0,0)!=0){ cw_log(LOG_ERR,"Fatal- Can't init semaphore for conn object: %s",strerror(errno)); conn_destroy(conn); return NULL; }; conn->recv_packet=conn_q_recv_packet; conn->recv_packet_peek=conn_q_recv_packet_peek; } else{ conn->recv_packet = conn_recv_packet; conn->recv_packet_peek = conn_recv_packet_peek; } conn->send_packet = conn_send_packet; // conn->send_data_packet = conn_send_data_packet; conn->last_seqnum_received=-1; conn->mtu=1500; conn->cur_packet=0; conn->recv_timeout=1; conn->seqnum=-1; conn->write = conn->send_packet; conn->read = conn->recv_packet; // conn->write_data = conn->send_data_packet; conn->dtls_mtu = 1500; return conn; }
ACIPLIST * do_discovery(const char *acaddr) { /* get an partially intialized connection object * (seqnum should be set) * */ struct conn * conn = get_conn(); if (!conn){ cw_log(LOG_ERR,"Can't create conn for %s: %s",acaddr,strerror(errno)); return 0; } /* get addr of destination */ struct addrinfo hints; struct addrinfo * res,*res0; memset(&hints,0,sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_family = PF_UNSPEC; int rc = getaddrinfo(acaddr,conf_control_port,&hints,&res0); if(rc){ cw_log(LOG_ERR,"Can't connect to AC %s: %s",acaddr,gai_strerror(rc)); return 0; } struct discovery_info di; memset (&di,0,sizeof(struct discovery_info)); di.aciplist = aciplist_create(); di.response_count=0; for(res=res0; res; res=res->ai_next) { if ( discovery_count >= conf_max_discoveries){ sulking_state(); discovery_count=0; cw_log_debug0("Entering discovery state"); } discovery_count++; /* create socket */ int sockfd; int opt; sockfd=socket(res->ai_family,SOCK_DGRAM,0); if (sockfd == -1){ cw_log(LOG_ERR,"Can't create socket for %s: %s",acaddr,strerror(errno)); continue; } opt = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt))<0){ cw_log(LOG_ERR,"Cant set broadcast sockopt"); } sock_set_recvtimeout(sockfd,1); sock_set_dontfrag(sockfd,0); di.conn=conn; sock_copyaddr(&conn->addr,res->ai_addr); conn->sock=sockfd; do_discover_conn(conn,&di); close(sockfd); if ( di.aciplist->count != 0) break; } freeaddrinfo(res0); if (di.aciplist->count){ cw_log_debug2("Discover responses received: %i\n",di.response_count); return di.aciplist; } aciplist_destroy(di.aciplist); return 0; }
struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr) { struct wtpman *wtpman; wtpman = malloc(sizeof(struct wtpman)); if (!wtpman) return 0; memset(wtpman, 0, sizeof(struct wtpman)); int replyfd; if (socklist[socklistindex].type != SOCKLIST_UNICAST_SOCKET) { int port = sock_getport(&socklist[socklistindex].addr); replyfd = socklist_find_reply_socket(srcaddr, port); if (replyfd == -1) { cw_log(LOG_ERR, "Can't find reply socket for request from %s", sock_addr2str(srcaddr)); free(wtpman); return NULL; } } else { replyfd = socklist[socklistindex].sockfd; } int sockfd = replyfd; //socklist[socklistindex].reply_sockfd; struct sockaddr dbgaddr; socklen_t dbgaddrl = sizeof(dbgaddr); getsockname(sockfd, &dbgaddr, &dbgaddrl); cw_dbg(DBG_INFO, "Creating wtpman on socket %d, %s:%d", sockfd, sock_addr2str(&dbgaddr), sock_getport(&dbgaddr)); //extern int conn_process_packet2(struct conn *conn, uint8_t * packet, int len, // struct sockaddr *from); wtpman->conn = conn_create(sockfd, srcaddr, 100); wtpman->conn->data_sock = socklist[socklistindex].data_sockfd; sock_copyaddr(&wtpman->conn->data_addr, (struct sockaddr *) &wtpman->conn->addr); // wtpman->conn->process_packet = conn_process_packet2; if (!wtpman->conn) { wtpman_destroy(wtpman); return NULL; } wtpman->conn->mods = conf_mods; wtpman->conn->strict_capwap = conf_strict_capwap; wtpman->conn->strict_hdr = conf_strict_headers; wtpman->conn->radios = mbag_i_create(); wtpman->conn->radios_upd = mbag_i_create(); wtpman->conn->local = ac_config; //wtpman->conn->capwap_mode=0; //CW_MODE_STD; //CISCO; wtpman->conn->capwap_mode = CW_MODE_CISCO; //wtpman->conn->strict_capwap_hdr=0; return wtpman; }