예제 #1
0
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;	
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
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;	
}
예제 #5
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;
}
예제 #6
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);    
}