int connection_rehandshake(dtls_connection_t *connP, bool sendCloseNotify) { // if not a dtls connection we do nothing if (connP->dtlsSession == NULL) { return 0; } // reset current session dtls_peer_t * peer = dtls_get_peer(connP->dtlsContext, connP->dtlsSession); if (peer != NULL) { if (!sendCloseNotify) { peer->state = DTLS_STATE_CLOSED; } dtls_reset_peer(connP->dtlsContext, peer); } // start a fresh handshake int result = dtls_connect(connP->dtlsContext, connP->dtlsSession); if (result !=0) { printf("error dtls reconnection %d\n",result); } return result; }
/*---------------------------------------------------------------------------*/ int coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port) { session_t session; if(coap_ctx == NULL || coap_ctx->is_used == 0) { return 0; } #ifdef NETSTACK_CONF_WITH_IPV6 memcpy(&coap_ctx->addr.in6_addr, addr, sizeof(coap_ctx->addr.in6_addr)); coap_ctx->addr.family = AF_INET6; #else memcpy(&coap_ctx->addr.in_addr, addr, sizeof(coap_ctx->addr.in_addr)); coap_ctx->addr.family = AF_INET; #endif coap_ctx->port = port; coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, (const struct net_addr *)&coap_ctx->addr, coap_ctx->port, (const struct net_addr *)&coap_ctx->my_addr, coap_ctx->my_port); if (!coap_ctx->net_ctx) { PRINTF("%s: Cannot get network context\n", __FUNCTION__); return 0; } uip_ipaddr_copy(&session.addr.ipaddr, addr); session.addr.port = UIP_HTONS(port); session.size = sizeof(session.addr); session.ifindex = 1; coap_ctx->status = STATUS_CONNECTING; PRINTF("coap-context: DTLS CONNECT TO ["); PRINT6ADDR(addr); PRINTF("]:%u\n", uip_ntohs(port)); if(dtls_connect(coap_ctx->dtls_context, &session) >= 0) { return 1; } /* Failed to initiate connection */ coap_ctx->status = STATUS_ALERT; return 0; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(udp_server_process, ev, data) { static int connected = 0; static session_t dst; PROCESS_BEGIN(); dtls_init(); init_dtls(&dst); serial_line_init(); if (!dtls_context) { dsrv_log(LOG_EMERG, "cannot create context\n"); PROCESS_EXIT(); } while(1) { PROCESS_YIELD(); if(ev == tcpip_event) { dtls_handle_read(dtls_context); } else if (ev == serial_line_event_message) { register size_t len = min(strlen(data), sizeof(buf) - buflen); memcpy(buf + buflen, data, len); buflen += len; if (buflen < sizeof(buf) - 1) buf[buflen++] = '\n'; /* serial event does not contain LF */ } if (buflen) { if (!connected) connected = dtls_connect(dtls_context, &dst) >= 0; try_send(dtls_context, &dst); } } PROCESS_END(); }
int main(int argc, char **argv) { dtls_context_t *dtls_context = NULL; fd_set rfds, wfds; struct timeval timeout; unsigned short port = DEFAULT_PORT; char port_str[NI_MAXSERV] = "0"; log_t log_level = LOG_WARN; int fd, result; int on = 1; int opt, res; session_t dst; dtls_init(); snprintf(port_str, sizeof(port_str), "%d", port); while ((opt = getopt(argc, argv, "p:o:v:")) != -1) { switch (opt) { case 'p' : strncpy(port_str, optarg, NI_MAXSERV-1); port_str[NI_MAXSERV - 1] = '\0'; break; case 'o' : output_file.length = strlen(optarg); output_file.s = (unsigned char *)malloc(output_file.length + 1); if (!output_file.s) { dsrv_log(LOG_CRIT, "cannot set output file: insufficient memory\n"); exit(-1); } else { /* copy filename including trailing zero */ memcpy(output_file.s, optarg, output_file.length + 1); } break; case 'v' : log_level = strtol(optarg, NULL, 10); break; default: usage(argv[0], PACKAGE_VERSION); exit(1); } } set_log_level(log_level); if (argc <= optind) { usage(argv[0], PACKAGE_VERSION); exit(1); } memset(&dst, 0, sizeof(session_t)); /* resolve destination address where server should be sent */ res = resolve_address(argv[optind++], &dst.addr.sa); if (res < 0) { dsrv_log(LOG_EMERG, "failed to resolve address\n"); exit(-1); } dst.size = res; /* use port number from command line when specified or the listen port, otherwise */ dst.addr.sin.sin_port = htons(atoi(optind < argc ? argv[optind++] : port_str)); /* init socket and set it to non-blocking */ fd = socket(dst.addr.sa.sa_family, SOCK_DGRAM, 0); if (fd < 0) { dsrv_log(LOG_ALERT, "socket: %s\n", strerror(errno)); return 0; } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) { dsrv_log(LOG_ALERT, "setsockopt SO_REUSEADDR: %s\n", strerror(errno)); } #if 0 flags = fcntl(fd, F_GETFL, 0); if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { dsrv_log(LOG_ALERT, "fcntl: %s\n", strerror(errno)); goto error; } #endif on = 1; #ifdef IPV6_RECVPKTINFO if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) { #else /* IPV6_RECVPKTINFO */ if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on) ) < 0) { #endif /* IPV6_RECVPKTINFO */ dsrv_log(LOG_ALERT, "setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); } dtls_context = dtls_new_context(&fd); if (!dtls_context) { dsrv_log(LOG_EMERG, "cannot create context\n"); exit(-1); } dtls_set_handler(dtls_context, &cb); dtls_connect(dtls_context, &dst); while (1) { FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(fileno(stdin), &rfds); FD_SET(fd, &rfds); /* FD_SET(fd, &wfds); */ timeout.tv_sec = 5; timeout.tv_usec = 0; result = select(fd+1, &rfds, &wfds, 0, &timeout); if (result < 0) { /* error */ if (errno != EINTR) perror("select"); } else if (result == 0) { /* timeout */ } else { /* ok */ if (FD_ISSET(fd, &wfds)) /* FIXME */; else if (FD_ISSET(fd, &rfds)) dtls_handle_read(dtls_context); else if (FD_ISSET(fileno(stdin), &rfds)) handle_stdin(); } if (len) try_send(dtls_context, &dst); } dtls_free_context(dtls_context); exit(0); }
int join(struct sockaddr *sa) { int sockfd; int rc; sockfd = socket(AF_INET,SOCK_DGRAM,0); if (sockfd==-1){ cw_log(LOG_ERR,"Can't create socket: %s\n",strerror(errno)); return -1; } sock_set_recvtimeout(sockfd,1); rc = connect(sockfd,(struct sockaddr*)sa,sock_addrlen((struct sockaddr*)sa)); if (rc<0){ char str[100]; sock_addrtostr(sa,str,100); cw_log(LOG_ERR,"Can't connect to %s: %s\n",str,strerror(errno)); close(sockfd); return -1; } struct conn * conn = get_conn(); conn->sock=sockfd; sock_copyaddr(&conn->addr,sa); #ifdef WITH_DTLS cw_dbg (DBG_DTLS,"Establishing DTLS session with %s",sock_addr2str(sa)); /* #ifdef WITH_CW_LOG_DEBUG { char str[100]; sock_addrtostr(sa,str,100); cw_log_debug0("Establishing DTLS connection to %s",str); } #endif */ if (conf_dtls_psk){ conn->dtls_psk=conf_dtls_psk; conn->dtls_psk_len=strlen(conn->dtls_psk); conn->dtls_cipher=conf_dtls_cipher; } if (conf_sslkeyfilename && conf_sslcertfilename){ conn->dtls_key_file = conf_sslkeyfilename; conn->dtls_cert_file = conf_sslcertfilename; conn->dtls_key_pass = conf_sslkeypass; conn->dtls_cipher=conf_dtls_cipher; } rc = dtls_connect(conn); if (rc!=1){ dtls_shutdown(conn); char str[100]; sock_addrtostr(sa,str,100); cw_log(LOG_ERR,"Cant establish DTLS connection to %s",str); close(sockfd); return 0; } #endif cw_dbg (DBG_DTLS,"DTLS session established with %s, cipher=%s",sock_addr2str(sa),dtls_get_cipher(conn)); exit(0); #ifdef WITH_CW_LOG_DEBUG { char str[100]; sock_addrtostr(sa,str,100); cw_log_debug0("DTLS connection to %s established",str); } #endif join_state(conn); return 1; }
static int start(struct allocation *alloc) { struct sa laddr; int err = 0; if (!alloc) return EINVAL; sa_init(&laddr, sa_af(&alloc->srv)); switch (alloc->proto) { case IPPROTO_UDP: err = udp_listen(&alloc->us, &laddr, udp_recv, alloc); if (err) { re_fprintf(stderr, "allocation: failed to" " create UDP socket" " (%m)\n", err); goto out; } udp_sockbuf_set(alloc->us, 524288); if (alloc->secure) { /* note: re-using UDP socket for DTLS-traffic */ err = dtls_listen(&alloc->dtls_sock, NULL, alloc->us, 2, DTLS_LAYER, NULL, NULL); if (err) { re_fprintf(stderr, "dtls_listen error: %m\n", err); goto out; } err = dtls_connect(&alloc->tlsc, alloc->tls, alloc->dtls_sock, &alloc->srv, dtls_estab_handler, dtls_recv_handler, dtls_close_handler, alloc); if (err) { re_fprintf(stderr, "dtls_connect error: %m\n", err); goto out; } } else { err = turnc_alloc(&alloc->turnc, NULL, IPPROTO_UDP, alloc->us, TURN_LAYER, &alloc->srv, alloc->user, alloc->pass, TURN_DEFAULT_LIFETIME, turnc_handler, alloc); if (err) { re_fprintf(stderr, "allocation: failed to" " create TURN client" " (%m)\n", err); goto out; } } break; case IPPROTO_TCP: err = tcp_connect(&alloc->tc, &alloc->srv, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, alloc); if (err) break; if (alloc->secure) { err = tls_start_tcp(&alloc->tlsc, alloc->tls, alloc->tc, 0); if (err) break; } break; default: err = EPROTONOSUPPORT; goto out; } out: return err; }
int main(int argc, char **argv) { int status = 0; struct sockaddr_in servaddr; int ret = 0; int server_port = 0; if (argc < 3) { fprintf (stderr, "Usage: %s <server_ip> <server_port>\n", argv[0]); assert (argc == 3); } // init_daemon(); // Enable this, to Daemonize the client server_port = atoi (argv[2]); if((status = creat_pidfile()) != 1) { syslog(LOG_ERR, "PID file could not be created...exiting"); doexit(EXIT_FAILURE); } sig_setup(); udpsock = socket(PF_INET, SOCK_DGRAM, 0); if (udpsock == -1) { syslog(LOG_ERR, "%s(): %s @ %d", __func__, strerror (errno), __LINE__); doexit(EXIT_FAILURE); } #if 1 memset((void *)&servaddr,'\0',sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(server_port); if ((servaddr.sin_addr.s_addr = pgethostbyname(argv[1])) < 0) { close(udpsock); syslog(LOG_ERR, "%s(): %s @ %d", __func__, strerror (errno), __LINE__); doexit(EXIT_FAILURE); } status = connect(udpsock, (struct sockaddr *) &servaddr ,sizeof(struct sockaddr_in)); if(status == -1) { syslog(LOG_ERR, "%s(): %s @ %d", __func__, strerror (errno), __LINE__); doexit(EXIT_FAILURE); } else #endif { ctx = dtls_setup_sslclient(); REDO: fprintf (stderr, "%s: %s(): Am here @ %d\n", __FILE__, __func__, __LINE__); ret = dtls_connect (); if (-1 == ret) goto END; else if (1 == ret) goto REDO; status = handle_data(ssl); if (status == -1) { syslog(LOG_ERR, "Unable to send beat : send failed[%s]...exiting", strerror(errno)); doexit(EXIT_FAILURE); } SSL_shutdown (ssl); } END: if (NULL != ssl) SSL_free (ssl); if (udpsock > 0) close(udpsock); closelog(); return 0; }