static inline ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size) { struct gnutella_socket *s = ptr; ssize_t ret; int saved_errno; socket_check(s); g_assert(is_valid_fd(s->file_desc)); ret = s_read(s->file_desc, buf, size); saved_errno = errno; tls_signal_pending(s); if ((ssize_t) -1 == ret) { tls_set_errno(s, saved_errno); if (!is_temporary_error(saved_errno)) { socket_connection_reset(s); } } else if (0 == ret) { socket_eof(s); } tls_transport_debug("tls_pull", s, size, ret); errno = saved_errno; return ret; }
int tls_init(struct gnutella_socket *s) { socket_check(s); g_assert_not_reached(); return -1; }
BOOL data_waiting(void* unused, unsigned timeout) { BOOL rd; if(!socket_check(sock,&rd,NULL,timeout)) return(FALSE); return(rd); }
static int socket_write(lua_State *L) { lua_apr_socket *object = socket_check(L, 1, 1); int nresults = write_buffer(L, &object->output); apr_status_t status = flush_buffer(L, &object->output, 1); if (status != APR_SUCCESS) return push_error_status(L, status); return nresults; }
asmlinkage int solaris_socket(int family, int type, int protocol) { int (*sys_socket)(int, int, int) = (int (*)(int, int, int))SYS(socket); type = socket_check (family, type); if (type < 0) return type; return sys_socket(family, type, protocol); }
static int socket_gc(lua_State *L) { lua_apr_socket *socket = socket_check(L, 1, 0); if (object_collectable((lua_apr_refobj*)socket)) { free_buffer(L, &socket->input.buffer); free_buffer(L, &socket->output.buffer); socket_close_impl(L, socket); } release_object((lua_apr_refobj*)socket); return 0; }
static int socket_tostring(lua_State *L) { lua_apr_socket *socket; socket = socket_check(L, 1, 0); if (socket->handle != NULL) lua_pushfstring(L, "%s (%p)", lua_apr_socket_type.friendlyname, socket->handle); else lua_pushfstring(L, "%s (closed)", lua_apr_socket_type.friendlyname); return 1; }
void tls_wio_link(struct gnutella_socket *s) { socket_check(s); s->wio.write = tls_write; s->wio.read = tls_read; s->wio.writev = tls_writev; s->wio.readv = tls_readv; s->wio.sendto = tls_no_sendto; s->wio.flush = tls_flush; }
static int socket_opt_set(lua_State *L) { apr_status_t status; lua_apr_socket *object; apr_int32_t option, value; object = socket_check(L, 1, 1); option = option_check(L, 2); value = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : luaL_checkinteger(L, 3); status = apr_socket_opt_set(object->handle, option, value); return push_status(L, status); }
int socket_fd_set(lua_State *L) { lua_apr_socket *object; apr_status_t status; apr_os_sock_t fd; object = socket_check(L, 1, 0); fd = luaL_checkinteger(L, 2); status = apr_os_sock_put(&object->handle, &fd, object->pool); return push_status(L, status); }
static int socket_listen(lua_State *L) { lua_apr_socket *object; apr_status_t status; apr_int32_t backlog = SOMAXCONN; object = socket_check(L, 1, 1); if (strcmp(lua_tostring(L, 2), "max") != 0) backlog = luaL_checkinteger(L, 2); status = apr_socket_listen(object->handle, backlog); return push_status(L, status); }
int socket_fd_get(lua_State *L) { apr_status_t status; lua_apr_socket *object; apr_os_sock_t fd; object = socket_check(L, 1, 1); status = apr_os_sock_get(&fd, object->handle); if (status != APR_SUCCESS) return push_error_status(L, status); lua_pushinteger(L, fd); return 1; }
static int socket_timeout_set(lua_State *L) { lua_apr_socket *object; apr_status_t status; apr_interval_time_t timeout; object = socket_check(L, 1, 1); if (lua_isnumber(L, 2)) timeout = luaL_checkinteger(L, 2); else timeout = lua_toboolean(L, 2) ? -1 : 0; status = apr_socket_timeout_set(object->handle, timeout); return push_status(L, status); }
static int socket_recvfrom(lua_State *L) { lua_apr_socket *object; apr_status_t status; apr_sockaddr_t address = { 0 }; apr_size_t buflen; apr_int32_t flags; char buffer[1024], ip_addr[APRMAXHOSTLEN]; char *bufptr; int i; /* Validate arguments. */ object = socket_check(L, 1, 1); buflen = luaL_optint(L, 2, sizeof buffer); /* Use dynamically allocated buffer only when necessary. */ bufptr = (buflen > sizeof buffer) ? lua_newuserdata(L, buflen) : &buffer[0]; flags = 0; status = apr_socket_recvfrom(&address, object->handle, flags, bufptr, &buflen); if (status != APR_SUCCESS) return push_error_status(L, status); /* Convert the socket address to a Lua table. */ lua_newtable(L); /* Get the IP address in numeric format. */ status = apr_sockaddr_ip_getbuf(ip_addr, sizeof ip_addr, &address); if (status == APR_SUCCESS) lua_pushstring(L, ip_addr), lua_setfield(L, -2, "address"); /* Get the port number. */ lua_pushnumber(L, address.port), lua_setfield(L, -2, "port"); /* Get the address family. */ for (i = 0; i < count(family_values); i++) if (family_values[i] == address.family) { lua_pushstring(L, family_options[i]); lua_setfield(L, -2, "family"); break; } /* Push the received data. */ lua_pushlstring(L, bufptr, buflen); /* Return address table and received data. */ return 2; }
static int socket_shutdown(lua_State *L) { const char *options[] = { "read", "write", "both", NULL }; const apr_shutdown_how_e values[] = { APR_SHUTDOWN_READ, APR_SHUTDOWN_WRITE, APR_SHUTDOWN_READWRITE }; lua_apr_socket *socket; apr_status_t status; apr_shutdown_how_e how; socket = socket_check(L, 1, 1); how = values[luaL_checkoption(L, 2, NULL, options)]; status = apr_socket_shutdown(socket->handle, how); return push_status(L, status); }
static int socket_opt_get(lua_State *L) { apr_status_t status; lua_apr_socket *object; apr_int32_t option, value; object = socket_check(L, 1, 1); option = option_check(L, 2); status = apr_socket_opt_get(object->handle, option, &value); if (status != APR_SUCCESS) return push_error_status(L, status); else if (option == APR_SO_SNDBUF || option == APR_SO_RCVBUF) lua_pushinteger(L, value); else lua_pushboolean(L, value); return 1; }
static int socket_accept(lua_State *L) { lua_apr_socket *server, *client = NULL; apr_status_t status; server = socket_check(L, 1, 1); status = socket_alloc(L, &client); client->family = server->family; client->protocol = server->protocol; if (status == APR_SUCCESS) status = apr_socket_accept(&client->handle, server->handle, client->pool); socket_init(L, client); if (status != APR_SUCCESS) return push_error_status(L, status); return 1; }
static int socket_connect(lua_State *L) { lua_apr_socket *object; apr_sockaddr_t *address; const char *host; apr_port_t port; apr_status_t status; object = socket_check(L, 1, 1); host = luaL_checkstring(L, 2); port = luaL_checkinteger(L, 3); status = apr_sockaddr_info_get(&address, host, object->family, port, 0, object->pool); if (status == APR_SUCCESS) status = apr_socket_connect(object->handle, address); return push_status(L, status); }
static int socket_timeout_get(lua_State *L) { lua_apr_socket *object; apr_status_t status; apr_interval_time_t timeout; object = socket_check(L, 1, 1); status = apr_socket_timeout_get(object->handle, &timeout); if (status != APR_SUCCESS) return push_error_status(L, status); else if (timeout <= 0) lua_pushboolean(L, timeout != 0); else lua_pushinteger(L, (lua_Integer) timeout); return 1; }
static int tls_flush(struct wrap_io *wio) { struct gnutella_socket *s = wio->ctx; socket_check(s); if (s->tls.snarf) { if (GNET_PROPERTY(tls_debug > 1)) { g_debug("tls_flush: snarf=%zu host=%s fd=%d", s->tls.snarf, host_addr_port_to_string(s->addr, s->port), s->file_desc); } (void ) tls_write_intern(wio, NULL, 0); if (s->tls.snarf) return -1; } return 0; }
/* main program */ int main(int argc, const char *argv[]) { sock.set_broadcast(); printf("Starting DSP code\n"); send_storage(); ardupilot_start(); while (true) { uint64_t now = micros64(); if (now - last_get_storage_us > 1000*1000) { printf("tick t=%.6f\n", now*1.0e-6f); ardupilot_heartbeat(); get_storage(); last_get_storage_us = now; } socket_check(); usleep(5000); } }
static ssize_t tls_write(struct wrap_io *wio, const void *buf, size_t size) { struct gnutella_socket *s = wio->ctx; ssize_t ret; socket_check(s); g_assert(socket_uses_tls(s)); g_assert(NULL != buf); g_assert(size_is_positive(size)); ret = tls_flush(wio); if (0 == ret) { ret = tls_write_intern(wio, buf, size); if (s->gdk_tag) { tls_socket_evt_change(s, INPUT_EVENT_WX); } } g_assert(ret == (ssize_t) -1 || (size_t) ret <= size); tls_signal_pending(s); return ret; }
void tls_free(struct gnutella_socket *s) { tls_context_t ctx; socket_check(s); ctx = s->tls.ctx; if (ctx) { if (ctx->session) { gnutls_deinit(ctx->session); } if (ctx->server_cred) { gnutls_anon_free_server_credentials(ctx->server_cred); ctx->server_cred = NULL; } if (ctx->client_cred) { gnutls_anon_free_client_credentials(ctx->client_cred); ctx->client_cred = NULL; } WFREE(ctx); s->tls.ctx = NULL; } }
static inline ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size) { struct gnutella_socket *s = ptr; ssize_t ret; int saved_errno; socket_check(s); g_assert(is_valid_fd(s->file_desc)); ret = s_write(s->file_desc, buf, size); saved_errno = errno; tls_signal_pending(s); if ((ssize_t) -1 == ret) { tls_set_errno(s, saved_errno); if (ECONNRESET == saved_errno || EPIPE == saved_errno) { socket_connection_reset(s); } } tls_transport_debug("tls_push", s, size, ret); errno = saved_errno; return ret; }
static int socket_addr_get(lua_State *L) { const char *options[] = { "local", "remote", NULL }; const apr_interface_e values[] = { APR_LOCAL, APR_REMOTE }; lua_apr_socket *object; apr_sockaddr_t *address; apr_status_t status; apr_interface_e which; char *ip_address; object = socket_check(L, 1, 1); which = values[luaL_checkoption(L, 2, "remote", options)]; status = apr_socket_addr_get(&address, which, object->handle); if (status == APR_SUCCESS) status = apr_sockaddr_ip_get(&ip_address, address); if (status != APR_SUCCESS) return push_error_status(L, status); lua_pushstring(L, ip_address); lua_pushinteger(L, address->port); lua_pushstring(L, address->hostname); return 3; }
void tls_bye(struct gnutella_socket *s) { int ret; socket_check(s); g_return_if_fail(s->tls.ctx); g_return_if_fail(s->tls.ctx->session); if ((SOCK_F_EOF | SOCK_F_SHUTDOWN) & s->flags) return; if (tls_flush(&s->wio) && GNET_PROPERTY(tls_debug)) { g_warning("%s(): tls_flush(fd=%d) failed", G_STRFUNC, s->file_desc); } ret = gnutls_bye(s->tls.ctx->session, SOCK_CONN_INCOMING != s->direction ? GNUTLS_SHUT_WR : GNUTLS_SHUT_RDWR); if (ret < 0) { switch (ret) { case GNUTLS_E_INTERRUPTED: case GNUTLS_E_AGAIN: break; case GNUTLS_E_PULL_ERROR: case GNUTLS_E_PUSH_ERROR: /* Logging already done by tls_transport_debug() */ break; default: if (GNET_PROPERTY(tls_debug)) { g_carp("gnutls_bye() failed: host=%s error=%m", host_addr_port_to_string(s->addr, s->port)); } } } }
/** * Change the monitoring condition on the socket. */ static void tls_socket_evt_change(struct gnutella_socket *s, inputevt_cond_t cond) { socket_check(s); g_assert(socket_with_tls(s)); /* No USES yet, may not have handshaked */ g_assert(INPUT_EVENT_EXCEPTION != cond); if (0 == s->gdk_tag) return; if (cond != s->tls.cb_cond) { int saved_errno = errno; if (GNET_PROPERTY(tls_debug) > 1) { int fd = socket_evt_fd(s); g_debug("tls_socket_evt_change: fd=%d, cond=%s -> %s", fd, inputevt_cond_to_string(s->tls.cb_cond), inputevt_cond_to_string(cond)); } inputevt_remove(&s->gdk_tag); socket_evt_set(s, cond, s->tls.cb_handler, s->tls.cb_data); errno = saved_errno; } }
bool sbbs_t::ftp_put(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest) { char cmd[512]; char rsp[512]; char path[MAX_PATH+1]; char buf[4097]; int rd; int result; ulong total=0; SOCKET data_sock; union xp_sockaddr addr; socklen_t addr_len; FILE* fp=NULL; bool error=false; struct timeval tv; fd_set socket_set; SAFECOPY(path,src); if(!fexistcase(path)) return(false); if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET) { bprintf("ftp: failure, line %d",__LINE__); return(false); } if(csi->ftp_mode&CS_FTP_PASV) { #if 0 // Debug bprintf("Connecting to %s:%hd\r\n" ,inet_ntoa(addr.in.sin_addr) ,ntohs(addr.in.sin_port)); #endif if(connect(data_sock,&addr.addr,sizeof(addr.in))!=0) { bprintf("ftp: failure, line %d",__LINE__); csi->socket_error=ERROR_VALUE; close_socket(data_sock); return(false); } } if((fp=fopen(path,"rb"))==NULL) { bprintf("ftp: failure, line %d",__LINE__); close_socket(data_sock); return(false); } sprintf(cmd,"STOR %s",dest); if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) || atoi(rsp)!=150 /* Open data connection */) { bprintf("ftp: failure, line %d",__LINE__); close_socket(data_sock); return(false); } if(!(csi->ftp_mode&CS_FTP_PASV)) { /* Normal (Active) FTP */ /* Setup for select() */ tv.tv_sec=TIMEOUT_SOCK_LISTEN; tv.tv_usec=0; FD_ZERO(&socket_set); FD_SET(data_sock,&socket_set); result=select(data_sock+1,&socket_set,NULL,NULL,&tv); if(result<1) { csi->socket_error=ERROR_VALUE; closesocket(data_sock); return(false); } SOCKET accept_sock; addr_len=sizeof(addr); if((accept_sock=accept_socket(data_sock,&addr,&addr_len)) ==INVALID_SOCKET) { csi->socket_error=ERROR_VALUE; closesocket(data_sock); return(false); } close_socket(data_sock); data_sock=accept_sock; } while(online && !feof(fp)) { rd=fread(buf,sizeof(char),sizeof(buf),fp); if(rd<1) /* EOF or READ error */ break; if(!socket_check(ctrl_sock,NULL,NULL,0)) break; /* Control connection lost */ if(sendsocket(data_sock,buf,rd)<1) { error=true; break; } total+=rd; if(csi->ftp_mode&CS_FTP_HASH) outchar('#'); } if(csi->ftp_mode&CS_FTP_HASH) { CRLF; } fclose(fp); close_socket(data_sock); if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) || atoi(rsp)!=226 /* Upload complete */) return(false); if(!error) bprintf("ftp: %lu bytes sent.\r\n", total); return(!error); }
bool sbbs_t::ftp_get(csi_t* csi, SOCKET ctrl_sock, char* src, char* dest, bool dir) { char cmd[512]; char rsp[512]; char buf[4097]; int rd; int result; BOOL data_avail; ulong total=0; SOCKET data_sock; union xp_sockaddr addr; socklen_t addr_len; FILE* fp=NULL; struct timeval tv; fd_set socket_set; if((data_sock=ftp_data_sock(csi, ctrl_sock, &addr.in))==INVALID_SOCKET) return(false); if(csi->ftp_mode&CS_FTP_PASV) { #if 0 // Debug bprintf("Connecting to %s:%hd\r\n" ,inet_ntoa(addr.in.sin_addr) ,ntohs(addr.in.sin_port)); #endif /* TODO: IPv6 */ if(connect(data_sock,&addr.addr,sizeof(SOCKADDR_IN))!=0) { csi->socket_error=ERROR_VALUE; close_socket(data_sock); return(false); } } if(dir) sprintf(cmd,"LIST %s",src); else sprintf(cmd,"RETR %s",src); if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) || atoi(rsp)!=150 /* Open data connection */) { close_socket(data_sock); return(false); } if(!(csi->ftp_mode&CS_FTP_PASV)) { /* Normal (Active) FTP */ /* Setup for select() */ tv.tv_sec=TIMEOUT_SOCK_LISTEN; tv.tv_usec=0; FD_ZERO(&socket_set); FD_SET(data_sock,&socket_set); result=select(data_sock+1,&socket_set,NULL,NULL,&tv); if(result<1) { csi->socket_error=ERROR_VALUE; closesocket(data_sock); return(false); } SOCKET accept_sock; addr_len=sizeof(addr); if((accept_sock=accept_socket(data_sock,&addr,&addr_len)) ==INVALID_SOCKET) { csi->socket_error=ERROR_VALUE; closesocket(data_sock); return(false); } close_socket(data_sock); data_sock=accept_sock; } if(!dir) if((fp=fopen(dest,"wb"))==NULL) { close_socket(data_sock); return(false); } while(online) { if(!socket_check(ctrl_sock,NULL,NULL,0)) break; /* Control connection lost */ if(!socket_check(data_sock,&data_avail,NULL,100)) break; /* Data connection lost */ if(!data_avail) continue; if((rd=recv(data_sock, buf, sizeof(buf)-1, 0))<1) break; if(dir) { buf[rd]=0; bputs(buf); } else fwrite(buf,1,rd,fp); total+=rd; if(!dir && csi->ftp_mode&CS_FTP_HASH) outchar('#'); } if(!dir && csi->ftp_mode&CS_FTP_HASH) { CRLF; } if(fp!=NULL) fclose(fp); close_socket(data_sock); if(!ftp_cmd(csi,ctrl_sock,NULL,rsp) || atoi(rsp)!=226 /* Download complete */) return(false); bprintf("ftp: %lu bytes received.\r\n", total); return(true); }
/* FTP Command/Response function */ bool sbbs_t::ftp_cmd(csi_t* csi, SOCKET sock, const char* cmdsrc, char* rsp) { char cmd[512]; int len; BOOL data_avail; time_t start; if(cmdsrc!=NULL) { sprintf(cmd,"%s\r\n",cmdsrc); if(csi->ftp_mode&CS_FTP_ECHO_CMD) bputs(cmd); len=strlen(cmd); if(sendsocket(sock,cmd,len)!=len) { csi->socket_error=ERROR_VALUE; return(FALSE); } } if(rsp!=NULL) { int rd; char ch; while(1) { rd=0; start=time(NULL); while(rd<500) { if(!online) return(FALSE); if(!socket_check(sock,&data_avail,NULL,1000)) return(FALSE); if(!data_avail) { if(time(NULL)-start>TIMEOUT_FTP_RESPONSE) { lprintf(LOG_WARNING,"!ftp_cmd: TIMEOUT_FTP_RESPONSE (%d) exceeded" ,TIMEOUT_FTP_RESPONSE); return(FALSE); } continue; } if(recv(sock, &ch, 1, 0)!=1) { csi->socket_error=ERROR_VALUE; return(FALSE); } if(ch=='\n' && rd>=1) break; rsp[rd++]=ch; } rsp[rd-1]=0; if(csi->ftp_mode&CS_FTP_ECHO_RSP) bprintf("%s\r\n",rsp); if(rsp[0]!=' ' && rsp[3]!='-') break; } } return(TRUE); }