/** * network_connect(sas, callback, cookie): * Iterate through the addresses in ${sas}, attempting to create and connect * a non-blocking socket. Once connected, invoke ${callback}(${cookie}, s) * where s is the connected socket; upon fatal error or if there are no * addresses remaining to attempt, invoke ${callback}(${cookie}, -1). Return * a cookie which can be passed to network_connect_cancel in order to cancel * the connection attempt. */ void * network_connect(struct sock_addr * const * sas, int (* callback)(void *, int), void * cookie) { struct connect_cookie * C; /* Bake a cookie. */ if ((C = malloc(sizeof(struct connect_cookie))) == NULL) goto err0; C->callback = callback; C->cookie = cookie; C->sas = sas; C->cookie_immediate = NULL; C->s = -1; /* Try to connect to the first address. */ if (tryconnect(C)) goto err0; /* Success! */ return (C); err0: /* Failure! */ return (NULL); }
void run(){ int len; int buffer_pos = 0; char tmpbuff[SIGNALING_BUFFER_SIZE]; getPeer()->onSignalingThreadStarted(); pthread_mutex_unlock(&startMutex); while(signalingContinue){ getPeer()->processMessages(); if(!isConnected){ isConnected = tryconnect(); sleep(1); } else if((len = recv(signalingSocket, signalingBuffer + buffer_pos, SIGNALING_BUFFER_SIZE - buffer_pos, 0)) > 0){ bool msgComplete = false; buffer_pos += len; do{ msgComplete = false; int msg_length = *(int*)signalingBuffer; if(buffer_pos > msg_length){ this->processMessage(signalingBuffer+4, msg_length ); memcpy(tmpbuff, signalingBuffer+4+msg_length, SIGNALING_BUFFER_SIZE - 4 - msg_length); memcpy(signalingBuffer, tmpbuff, SIGNALING_BUFFER_SIZE - 4 - msg_length); buffer_pos -= (4 + msg_length); msgComplete = true; } }while(msgComplete && buffer_pos > 0); }else if(len == 0){ //std::cout << "[SIG] Disconnected" << std::endl; isConnected = false; close(signalingSocket); getPeer()->disconnect(); } } close(signalingSocket); getPeer()->onSignalingThreadStopped(); delete getPeer(); //TODO deleting peer segfaults while terminating audio stack !! pthread_mutex_unlock(&stopMutex); //std::cout << "[SIG] Quit" << std::endl; }
void ChatCore::add_UI(QObject *ui_core) { this->ui_core=ui_core; QObject::connect(ui_core, SIGNAL(loginSignal(QString, QString, QString)), this, SLOT(tryconnect(QString, QString, QString))); QObject::connect(ui_core, SIGNAL(disconnectSignal()), this, SLOT(disconnect())); QObject::connect(ui_core, SIGNAL(sendMessSignal(QString, QString)), this, SLOT(send_mess(QString, QString))); }
virtual void start() { isConnected = tryconnect(); signalingContinue = true; pthread_mutex_lock(&startMutex); signalingThread = std::thread([&](){ this->run(); }); pthread_mutex_lock(&startMutex); pthread_mutex_unlock(&startMutex); }
static int cmd_process(struct silly_socket *ss) { int close = 0; while (hascmd(ss)) { int err; struct cmdpacket cmd; err = pipe_blockread(ss->ctrlrecvfd, &cmd); if (err < 0) continue; switch (cmd.type) { case 'L': trylisten(ss, &cmd); break; case 'B': tryudpbind(ss, &cmd); break; case 'C': tryconnect(ss, &cmd); break; case 'O': tryudpconnect(ss, &cmd); break; case 'K': if (tryclose(ss, &cmd) == 0) close = 1; break; case 'S': if (trysend(ss, &cmd) < 0) close = 1; break; case 'U': tryudpsend(ss, &cmd); //udp socket can only be closed active break; case 'T': //just to return from sp_wait close = -1; break; default: fprintf(stderr, "[socket] cmd_process:unkonw operation:%d\n", cmd.type); assert(!"oh, no!"); break; } } return close; }
/** * DESCRIPTION * Creates a socket and attempts to connect to the first available address in addreses. * FIELDS * __sockfd is set to the socket identifier * RETURN VALUE * Returns connection status code, 0 is connection OK. **/ int connectaddr(struct addrinfo *addreses, int *__sockfd) { struct addrinfo *current; // current is first element in linked list ... current = addreses; int sockfd; int connstatus; while(current != NULL){ void *ip; int family = current->ai_family; printf("family: %d", family); unsigned short int port; if(family == AF_INET){ // IPv4 => current can be cast to puts("IPv4"); struct sockaddr_in *adr; adr = (struct sockaddr_in *)current->ai_addr; port = adr->sin_port; ip = &adr->sin_addr; }else if(family == AF_INET6){ // IPv6 => current can be cast to puts("IPv6"); struct sockaddr_in6 *adr; adr = (struct sockaddr_in6 *)current->ai_addr; ip = &adr->sin6_addr; port = adr->sin6_port; }else{ puts("Neither IPv4 or IPv6"); } char dst[INET6_ADDRSTRLEN]; // IPv6 max address >> IPv4 max address ... //Convert binary ip address to dotted decimal ... Store result in dst ... inet_ntop(family, ip, dst, sizeof dst); printf("\tip%d: %s \tport: %d\n", family % 6 + 2, dst, port); // Try to connect ... If connection fails we iterate to next provided address ... // Note that this works for both IPv4 and IPv6 addresses! connstatus = tryconnect(current, &sockfd); if(connstatus == 0) // Successfully Connected break; current = current->ai_next; } *__sockfd = sockfd; return connstatus; }
/* Callback when connect(2) succeeds or fails. */ static int callback_connect(void * cookie) { struct connect_cookie * C = cookie; int sockerr; socklen_t sockerrlen = sizeof(int); /* Did we succeed? */ if (getsockopt(C->s, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen)) goto err1; if (sockerr != 0) goto failed; /* * Perform the callback (this can be done here rather than being * scheduled as an immediate callback, as we're already running from * callback context). */ return (docallback(C)); failed: /* Close the socket which failed to connect. */ close(C->s); /* We don't have an open socket any more. */ C->s = -1; /* This address didn't work. */ C->sas++; /* Try other addresses until we run out of options. */ return (tryconnect(C)); err1: close(C->s); free(C); /* Fatal error! */ return (-1); }
int main(int argc, char **argv) { init(&argc, &argv, &g_sett); atexit(cleanup); #if HAVE_SIGINFO lsi_b_regsig(SIGINFO, infohnd); #elif HAVE_SIGUSR1 lsi_b_regsig(SIGUSR1, infohnd); #endif bool failure = true; for (;;) { if (!irc_online(g_irc)) { D("connecting..."); if (tryconnect()) { g_nexthb = lsi_b_tstamp_us() + g_sett.heartbeat_us; continue; } W("failed to connect/logon (%s)", g_sett.recon ? "retrying" : "giving up"); if (!g_sett.recon) break; lsi_b_usleep(1000000ul * g_sett.cfwait_s); continue; } tokarr tok; uint64_t to = g_sett.heartbeat_us; int r = irc_read(g_irc, &tok, to ? to : 1000000); if (r < 0) break; if (g_dumpplx) { irc_dump(g_irc); if (irc_tracking_enab(g_irc)) lsi_trk_dump(g_irc, false); g_dumpplx = false; } if (r > 0) g_nexthb = lsi_b_tstamp_us() + g_sett.heartbeat_us; else if (g_sett.heartbeat_us && g_nexthb <= lsi_b_tstamp_us()) { iprintf("PING %s\r\n", irc_myhost(g_irc)); g_nexthb = lsi_b_tstamp_us() + g_sett.heartbeat_us; } if (r == 0) continue; if (strcmp(tok[1], "PING") == 0) iprintf("PONG :%s\r\n", tok[2]); else if (strcmp(tok[1], "PRIVMSG") == 0) { if (strncmp(tok[3], "ECHO ", 5) == 0) { char nick[64]; lsi_ut_ident2nick(nick, sizeof nick, tok[0]); iprintf("PRIVMSG %s :%s\r\n", nick, tok[3]+5); } else if (strncmp(tok[3], "DO ", 3) == 0) { iprintf("%s\r\n", tok[3]+3); } else if (strcmp(tok[3], "DIE") == 0) { failure = false; break; } else if (strcmp(tok[3], "DUMP") == 0) { irc_dump(g_irc); lsi_trk_dump(g_irc, false); } else if (strcmp(tok[3], "FULLDUMP") == 0) { irc_dump(g_irc); lsi_trk_dump(g_irc, true); } } } return failure ? EXIT_FAILURE : EXIT_SUCCESS; }