int kn_sock_sslconnect(//engine_t e, handle_t h, kn_sockaddr *remote, kn_sockaddr *local){ if(h->type != KN_SOCKET && ((kn_socket*)h)->type != SOCK_STREAM) return 0; kn_socket *s = (kn_socket*)h; if(h->status != SOCKET_NONE) return -1; //if(s->e) return -1; SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); if (ctx == NULL) { ERR_print_errors_fp(stdout); return -1; } ((kn_stream_socket*)s)->ctx = ctx; s->addr_remote = *remote; int ret = stream_socket_connect((kn_stream_socket*)s,local,remote); if(ret == 1){ ((kn_stream_socket*)s)->ssl = SSL_new(ctx); SSL_set_fd(((kn_stream_socket*)s)->ssl,h->fd); if (SSL_connect(((kn_stream_socket*)s)->ssl) == -1){ ERR_print_errors_fp(stderr); ret = -1; } else { kn_set_noblock(h->fd,0); h->status = SOCKET_ESTABLISH; printf("Connected with %s encryption/n", SSL_get_cipher(((kn_stream_socket*)s)->ssl)); ShowCerts(((kn_stream_socket*)s)->ssl); } }else{ ret = -1; } return ret; }
handle_t kn_new_chrdev(int fd){ struct stat buf; if(0 != fstat(fd,&buf)) return NULL; if(!S_ISCHR(buf.st_mode)) return NULL; kn_chr_dev *r = calloc(1,sizeof(*r)); ((handle_t)r)->fd = fd; kn_set_noblock(fd,0); ((handle_t)r)->type = KN_CHRDEV; ((handle_t)r)->on_events = on_events; return (handle_t)r; }
static int stream_socket_associate(engine_t e,handle_t h,void (*callback)(handle_t,void*,int,int)){ if(((handle_t)h)->type != KN_SOCKET) return -1; kn_socket *s = (kn_socket*)h; if(!callback) return -1; if(s->e){ kn_event_del(s->e,h); s->e = NULL; } if(h->status == SOCKET_ESTABLISH){ kn_set_noblock(h->fd,0); #ifdef _LINUX kn_event_add(e,h,EVENT_WRITE | EVENT_READ); #elif _BSD kn_event_add(e,h,EVENT_WRITE); kn_event_add(e,h,EVENT_READ); //kn_disable_read(e,h); //kn_disable_write(e,h); #else return -1; #endif }else if(h->status == SOCKET_LISTENING){ #ifdef _LINUX kn_event_add(e,h,EVENT_READ); #elif _BSD kn_event_add(e,EVENT_READ); #else return -1; #endif }else if(h->status == SOCKET_CONNECTING){ #ifdef _LINUX kn_event_add(e,h,EVENT_WRITE | EVENT_READ); #elif _BSD kn_event_add(e,h,EVENT_WRITE); kn_event_add(e,h,EVENT_READ); #else return -1; #endif } else{ return -1; } s->callback = callback; s->e = e; return 0; }
int stream_socket_connect(kn_stream_socket *ss, kn_sockaddr *local, kn_sockaddr *remote) { int fd = ((handle_t)ss)->fd; if(!ss->ctx) kn_set_noblock(fd,0); socklen_t len; if(local){ if(_bind(fd,local) < 0){ return -1; } } int ret; if(((kn_socket*)ss)->domain == AF_INET) ret = connect(fd,(const struct sockaddr *)&remote->in,sizeof(remote->in)); else if(((kn_socket*)ss)->domain == AF_INET6) ret = connect(fd,(const struct sockaddr *)&remote->in6,sizeof(remote->in6)); else if(((kn_socket*)ss)->domain == AF_LOCAL) ret = connect(fd,(const struct sockaddr *)&remote->un,sizeof(remote->un)); else{ return -1; } if(ret < 0 && errno != EINPROGRESS){ return -1; } if(ret == 0){ if(!local){ ((kn_socket*)ss)->addr_local.addrtype = ((kn_socket*)ss)->domain; if(((kn_socket*)ss)->addr_local.addrtype == AF_INET){ len = sizeof(((kn_socket*)ss)->addr_local.in); getsockname(fd,(struct sockaddr*)&((kn_socket*)ss)->addr_local.in,&len); }else if(((kn_socket*)ss)->addr_local.addrtype == AF_INET6){ len = sizeof(((kn_socket*)ss)->addr_local.in6); getsockname(fd,(struct sockaddr*)&((kn_socket*)ss)->addr_local.in6,&len); }else{ len = sizeof(((kn_socket*)ss)->addr_local.un); getsockname(fd,(struct sockaddr*)&((kn_socket*)ss)->addr_local.un,&len); } } ((handle_t)ss)->status = SOCKET_ESTABLISH; return 1; } ((handle_t)ss)->status = SOCKET_CONNECTING; return 0; }
int stream_socket_listen(kn_stream_socket *ss,kn_sockaddr *local) { if(((handle_t)ss)->status != SOCKET_NONE) return -1; int fd = ((handle_t)ss)->fd; kn_set_noblock(fd,0); int32_t yes = 1; if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) return -1; if(_bind(fd,local) < 0){ return -1; } if(listen(fd,SOMAXCONN) < 0){ return -1; } ((kn_socket*)ss)->addr_local = *local; ((handle_t)ss)->status = SOCKET_LISTENING; return 0; }
int kn_sock_ssllisten(handle_t h, kn_sockaddr *addr, const char *certificate, const char *privatekey ){ if(h->type != KN_SOCKET && ((kn_socket*)h)->type != SOCK_STREAM) return 0; kn_stream_socket *ss = (kn_stream_socket*)h; if(h->status != SOCKET_NONE) return -1; /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */ SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */ if (ctx == NULL) { ERR_print_errors_fp(stdout); return -1; } /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */ if (SSL_CTX_use_certificate_file(ctx,certificate, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return -1; } /* 载入用户私钥 */ if (SSL_CTX_use_PrivateKey_file(ctx, privatekey, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return -1; } /* 检查用户私钥是否正确 */ if (!SSL_CTX_check_private_key(ctx)) { ERR_print_errors_fp(stdout); SSL_CTX_free(ctx); return -1; } kn_set_noblock(((handle_t)ss)->fd,0); ss->ctx = ctx; return stream_socket_listen(ss,addr); }