bool KviHttpRequest::doConnect() { m_p->uPort = m_url.port(); if(m_p->uPort == 0) m_p->uPort = m_p->bIsSSL ? 443 : 80; if(m_p->pSocket) closeSocket(); #ifdef COMPILE_SSL_SUPPORT m_p->pSocket = m_p->bIsSSL ? new QSslSocket() : new QTcpSocket(); #else m_p->pSocket = new QTcpSocket(); #endif QObject::connect(m_p->pSocket,SIGNAL(connected()),this,SLOT(slotSocketConnected())); QObject::connect(m_p->pSocket,SIGNAL(disconnected()),this,SLOT(slotSocketDisconnected())); QObject::connect(m_p->pSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketError(QAbstractSocket::SocketError))); QObject::connect(m_p->pSocket,SIGNAL(readyRead()),this,SLOT(slotSocketReadDataReady())); QObject::connect(m_p->pSocket,SIGNAL(hostFound()),this,SLOT(slotSocketHostResolved())); emit resolvingHost(m_url.host()); #ifdef COMPILE_SSL_SUPPORT if(m_p->bIsSSL) { static_cast<QSslSocket *>(m_p->pSocket)->setProtocol(QSsl::AnyProtocol); static_cast<QSslSocket *>(m_p->pSocket)->connectToHostEncrypted(m_url.host(),m_p->uPort); } else { m_p->pSocket->connectToHost(m_url.host(),m_p->uPort); } #else m_p->pSocket->connectToHost(m_url.host(),m_p->uPort); #endif if(m_p->pConnectTimeoutTimer) { delete m_p->pConnectTimeoutTimer; m_p->pConnectTimeoutTimer = NULL; } m_p->pConnectTimeoutTimer = new QTimer(); m_p->pConnectTimeoutTimer->setSingleShot(true); QObject::connect(m_p->pConnectTimeoutTimer,SIGNAL(timeout()),this,SLOT(slotConnectionTimedOut())); m_p->pConnectTimeoutTimer->start(m_uConnectionTimeout * 1000); /* m_pThread = new KviHttpRequestThread( this, m_url.host(), m_szIp, uPort, m_url.path(), m_uContentOffset, (m_eProcessingType == HeadersOnly) ? KviHttpRequestThread::Head : (m_szPostData.isEmpty() ? KviHttpRequestThread::Get : KviHttpRequestThread::Post), m_szPostData, m_url.protocol()=="https" ); */ return true; }
void startServer(int port) { // Make sure types have the required size. assert(sizeof(bits8) == 1); assert(sizeof(bits16) == 2); assert(sizeof(bits32) == 4); int parsedValues; #ifdef _WIN32 WSADATA wsaData; WSAStartup(0x0202, &wsaData); #endif int sock = makeSocket(port); char req[REQ_SIZE + 1]; req[REQ_SIZE] = 0; while (1) { int conn = waitForConnection(sock); recv(conn, req, REQ_SIZE, 0); // Cut the string off to one line. char *endOfLine = strchr(req, '\n'); if (endOfLine != NULL) { *endOfLine = '\0'; } // Find the path. char path[PATH_SIZE + 1]; parsedValues = sscanf(req, "GET %s HTTP/1.1", path); if (parsedValues == 1) { if (strcmp(path, "/") == 0) { // Homepage char *msg = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "\r\n" "<!DOCTYPE html>\n" "<script src=\"http://almondbread.cse.unsw.edu.au/tiles.js\"></script>\n"; send(conn, msg, strlen(msg), 0); } else { double x, y; int zoom; parsedValues = sscanf( path, "/tile_x%lf_y%lf_z%d.bmp", &x, &y, &zoom); if (parsedValues == 3) { char *msg = "HTTP/1.0 200 OK\r\n" "Content-Type: image/bmp\r\n" "\r\n"; send(conn, msg, strlen(msg), 0); char image[FILE_SIZE]; mandelBitmap(image, x, y, zoom); send(conn, image, FILE_SIZE, 0); } else { // HTTP Error 404. } } } else { // HTTP Error 400. } closeSocket(conn); } // Closing the socket is unnecessary, because the OS will // immediately recover it thanks to SO_REUSEADDR. }
/* * Given an invalid Fd in *dst, try to open a unix socket connection to the * given path. */ static void openSocket(int *dst, char *path) { const int save_errno = errno; struct sockaddr_un addr; bool formed; int fd = -1; StringInfoData startup; /* * This procedure is only defined on the domain of invalidated file * descriptors */ Assert(*dst < 0); /* Begin attempting connection, first by forming the address */ formed = formAddr(&addr, path); if (!formed) { /* Didn't work, give up */ goto err; } /* Get socket fd, or die */ fd = socket(AF_LOCAL, SOCK_STREAM, 0); if (fd < 0) goto err; /* Connect socket to server. Or die. */ Assert(formed); do { int res; errno = 0; res = connect(fd, (void *) &addr, sizeof addr); if (res < 0 || (errno != EINTR && errno != 0)) goto err; } while (errno == EINTR); /* * Connection established. * * Try to send start-up information as a service to the caller. Should * this fail, sendOrInval will close and invalidate the socket, though. */ Assert(fd >= 0); initStringInfo(&startup); /* Prepare startup: protocol version ('V') frame */ { const uint32_t nVlen = htobe32((sizeof PROTO_VERSION) + sizeof(u_int32_t)); appendStringInfoChar(&startup, 'V'); appendBinaryStringInfo(&startup, (void *) &nVlen, sizeof nVlen); appendBinaryStringInfo(&startup, PROTO_VERSION, sizeof PROTO_VERSION); } /* Prepare startup: system identification ('I') frame */ { char *payload; int payloadLen; uint32_t nPayloadLen; if (ident == NULL) payload = ""; else payload = ident; payloadLen = strlen(payload) + sizeof '\0'; nPayloadLen = htobe32(payloadLen + sizeof nPayloadLen); appendStringInfoChar(&startup, 'I'); appendBinaryStringInfo(&startup, (void *) &nPayloadLen, sizeof nPayloadLen); appendBinaryStringInfo(&startup, (void *) payload, payloadLen); } /* * Try to send the prepared startup packet, invaliding fd if things go * awry. */ sendOrInval(&fd, startup.data, startup.len); pfree(startup.data); *dst = fd; goto exit; err: /* Close and invalidate 'fd' if it got made */ if (fd >= 0) { closeSocket(&fd); Assert(fd < 0); } Assert(*dst < 0); goto exit; exit: /* Universal post-condition */ errno = save_errno; return; }
static void logfebe_emit_log_hook(ErrorData *edata) { int save_errno; StringInfoData buf; /* * This is one of the few places where we'd rather not inherit a static * variable's value from the postmaster. But since we will, reset it when * MyProcPid changes. */ if (savedPid != MyProcPid) { savedPid = MyProcPid; /* Invalidate all inherited values */ seqNum = 0; cachedBackendStartTime[0] = '\0'; if (outSockFd >= 0) { closeSocket(&outSockFd); } } /* * Increment log sequence number * * Done early on so this happens regardless if there are problems emitting * the log. */ seqNum += 1; /* * Early exit if the socket path is not set and isn't in the format of * an absolute path. * * The empty identity ("ident") is a valid one, so it is not rejected in * the same way an empty logUnixSocketPath is. */ if (logUnixSocketPath == NULL || strlen(logUnixSocketPath) <= 0 || logUnixSocketPath[0] != '/') { /* * Unsetting the GUCs via SIGHUP would leave a connection * dangling, if it exists, close it. */ if (outSockFd >= 0) { closeSocket(&outSockFd); } goto quickExit; } save_errno = errno; /* * Initialize StringInfoDatas early, because pfree is called * unconditionally at exit. */ initStringInfo(&buf); if (outSockFd < 0) { openSocket(&outSockFd, logUnixSocketPath); /* Couldn't get a valid socket; give up */ if (outSockFd < 0) goto exit; } /* * Make room for message type byte and length header. The length header * must be overwritten to the correct value at the end. */ { const char logHdr[5] = {'L', '\0', '\0', '\0', '\0'}; appendBinaryStringInfo(&buf, logHdr, sizeof logHdr); } /* * Format the output, and figure out how long it is, and frame it * for the protocol. */ { uint32_t *msgSize; fmtLogMsg(&buf, edata); /* * Check that buf is prepared properly, with enough space and * the placeholder length expected. */ Assert(buf.len > 5); Assert(buf.data[0] == 'L'); msgSize = (uint32_t *)(buf.data + 1); Assert(*msgSize == 0); /* * Fill in *msgSize: buf contains the msg header, which is not * included in length; subract and byte-swap to paste the * right length into place. */ *msgSize = htobe32(buf.len - 1); } /* Finally: try to send the constructed message */ sendOrInval(&outSockFd, buf.data, buf.len); exit: pfree(buf.data); errno = save_errno; quickExit: /* Call a previous hook, should it exist */ if (prev_emit_log_hook != NULL) prev_emit_log_hook(edata); }
~WebInputStream() { closeSocket(); }
/* * Useful for HUP triggered reassignment: invalidate the socket, which will * cause path information to be evaluated when reconnection and identification * to be re-exchanged. */ static void gucOnAssignCloseInvalidate(const char *newval, void *extra) { closeSocket(&outSockFd); }
netAddressBits ourIPAddress(UsageEnvironment& env) { static netAddressBits ourAddress = 0; int sock = -1; struct in_addr testAddr; if (ReceivingInterfaceAddr != INADDR_ANY) { // Hack: If we were told to receive on a specific interface address, then // define this to be our ip address: ourAddress = ReceivingInterfaceAddr; } if (ourAddress == 0) { // We need to find our source address struct sockaddr_in fromAddr; fromAddr.sin_addr.s_addr = 0; // Get our address by sending a (0-TTL) multicast packet, // receiving it, and looking at the source address used. // (This is kinda bogus, but it provides the best guarantee // that other nodes will think our address is the same as we do.) do { loopbackWorks = 0; // until we learn otherwise testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary Port testPort(15947); // ditto sock = setupDatagramSocket(env, testPort); if (sock < 0) break; if (!socketJoinGroup(env, sock, testAddr.s_addr)) break; unsigned char testString[] = "hostIdTest"; unsigned testStringLength = sizeof testString; if (!writeSocket(env, sock, testAddr, testPort, 0, testString, testStringLength)) break; // Block until the socket is readable (with a 5-second timeout): fd_set rd_set; FD_ZERO(&rd_set); FD_SET((unsigned)sock, &rd_set); const unsigned numFds = sock+1; struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; int result = select(numFds, &rd_set, NULL, NULL, &timeout); if (result <= 0) break; unsigned char readBuffer[20]; int bytesRead = readSocket(env, sock, readBuffer, sizeof readBuffer, fromAddr); if (bytesRead != (int)testStringLength || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) { break; } // We use this packet's source address, if it's good: loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr); } while (0); if (sock >= 0) { socketLeaveGroup(env, sock, testAddr.s_addr); closeSocket(sock); } if (!loopbackWorks) do { // We couldn't find our address using multicast loopback, // so try instead to look it up directly - by first getting our host name, and then resolving this host name char hostname[100]; hostname[0] = '\0'; int result = gethostname(hostname, sizeof hostname); if (result != 0 || hostname[0] == '\0') { env.setResultErrMsg("initial gethostname() failed"); break; } // Try to resolve "hostname" to an IP address: NetAddressList addresses(hostname); NetAddressList::Iterator iter(addresses); NetAddress const* address; // Take the first address that's not bad: netAddressBits addr = 0; while ((address = iter.nextAddress()) != NULL) { netAddressBits a = *(netAddressBits*)(address->data()); if (!badAddressForUs(a)) { addr = a; break; } } // Assign the address that we found to "fromAddr" (as if the 'loopback' method had worked), to simplify the code below: fromAddr.sin_addr.s_addr = addr; } while (0); // Make sure we have a good address: netAddressBits from = fromAddr.sin_addr.s_addr; if (badAddressForUs(from)) { char tmp[100]; sprintf(tmp, "This computer has an invalid IP address: %s", AddressString(from).val()); env.setResultMsg(tmp); from = 0; } ourAddress = from; // Use our newly-discovered IP address, and the current time, // to initialize the random number generator's seed: struct timeval timeNow; gettimeofday(&timeNow, NULL); unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec; our_srandom(seed); } return ourAddress; }
int setupDatagramSocket(UsageEnvironment& env, Port port) { if (!initializeWinsockIfNecessary()) { socketErr(env, "Failed to initialize 'winsock': "); return -1; } int newSocket = createSocket(SOCK_DGRAM); if (newSocket < 0) { socketErr(env, "unable to create datagram socket: "); return newSocket; } int reuseFlag = groupsockPriv(env)->reuseFlag; reclaimGroupsockPriv(env); if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseFlag, sizeof reuseFlag) < 0) { socketErr(env, "setsockopt(SO_REUSEADDR) error: "); closeSocket(newSocket); return -1; } #if defined(__WIN32__) || defined(_WIN32) // Windoze doesn't properly handle SO_REUSEPORT or IP_MULTICAST_LOOP #else #ifdef SO_REUSEPORT if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseFlag, sizeof reuseFlag) < 0) { socketErr(env, "setsockopt(SO_REUSEPORT) error: "); closeSocket(newSocket); return -1; } #endif #ifdef IP_MULTICAST_LOOP const u_int8_t loop = 1; if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loop, sizeof loop) < 0) { socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: "); closeSocket(newSocket); return -1; } #endif #endif // Note: Windoze requires binding, even if the port number is 0 netAddressBits addr = INADDR_ANY; #if defined(__WIN32__) || defined(_WIN32) #else if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { #endif if (port.num() == 0) addr = ReceivingInterfaceAddr; MAKE_SOCKADDR_IN(name, addr, port.num()); if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { char tmpBuffer[100]; sprintf(tmpBuffer, "bind() error (port number: %d): ", ntohs(port.num())); socketErr(env, tmpBuffer); closeSocket(newSocket); return -1; } #if defined(__WIN32__) || defined(_WIN32) #else } #endif // Set the sending interface for multicasts, if it's not the default: if (SendingInterfaceAddr != INADDR_ANY) { struct in_addr addr; addr.s_addr = SendingInterfaceAddr; if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&addr, sizeof addr) < 0) { socketErr(env, "error setting outgoing multicast interface: "); closeSocket(newSocket); return -1; } } return newSocket; }
int setupStreamSocket(UsageEnvironment& env, Port port, Boolean makeNonBlocking) { if (!initializeWinsockIfNecessary()) { socketErr(env, "Failed to initialize 'winsock': "); return -1; } int newSocket = createSocket(SOCK_STREAM); if (newSocket < 0) { socketErr(env, "unable to create stream socket: "); return newSocket; } int reuseFlag = groupsockPriv(env)->reuseFlag; reclaimGroupsockPriv(env); if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseFlag, sizeof reuseFlag) < 0) { socketErr(env, "setsockopt(SO_REUSEADDR) error: "); closeSocket(newSocket); return -1; } // SO_REUSEPORT doesn't really make sense for TCP sockets, so we // normally don't set them. However, if you really want to do this // #define REUSE_FOR_TCP #ifdef REUSE_FOR_TCP #if defined(__WIN32__) || defined(_WIN32) // Windoze doesn't properly handle SO_REUSEPORT #else #ifdef SO_REUSEPORT if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseFlag, sizeof reuseFlag) < 0) { socketErr(env, "setsockopt(SO_REUSEPORT) error: "); closeSocket(newSocket); return -1; } #endif #endif #endif // Note: Windoze requires binding, even if the port number is 0 #if defined(__WIN32__) || defined(_WIN32) #else if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) { #endif MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num()); if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) { char tmpBuffer[100]; sprintf(tmpBuffer, "bind() error (port number: %d): ", ntohs(port.num())); socketErr(env, tmpBuffer); closeSocket(newSocket); return -1; } #if defined(__WIN32__) || defined(_WIN32) #else } #endif if (makeNonBlocking) { if (!makeSocketNonBlocking(newSocket)) { socketErr(env, "failed to make non-blocking: "); closeSocket(newSocket); return -1; } } return newSocket; }
Socket::~Socket() { closeSocket(fSocketNum); }
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec) { SOCKET s; struct sockaddr_in6 addr; int err; #if defined(LC_DARWIN) || defined(FIONBIO) int val; #endif s = socket(dstaddr->ss_family, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { Limelog("socket() failed: %d\n", (int)LastSocketError()); return INVALID_SOCKET; } #ifdef LC_DARWIN // Disable SIGPIPE on iOS val = 1; setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val)); #endif #ifdef FIONBIO // Enable non-blocking I/O for connect timeout support val = 1; ioctlsocket(s, FIONBIO, &val); #endif // Start connection memcpy(&addr, dstaddr, sizeof(addr)); addr.sin6_port = htons(port); err = connect(s, (struct sockaddr*) &addr, addrlen); if (err < 0) { err = (int)LastSocketError(); } #ifdef FIONBIO { struct fd_set writefds, exceptfds; struct timeval tv; FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(s, &writefds); FD_SET(s, &exceptfds); tv.tv_sec = timeoutSec; tv.tv_usec = 0; // Wait for the connection to complete or the timeout to elapse err = select(s + 1, NULL, &writefds, &exceptfds, &tv); if (err < 0) { // select() failed err = LastSocketError(); Limelog("select() failed: %d\n", err); closeSocket(s); SetLastSocketError(err); return INVALID_SOCKET; } else if (err == 0) { // select() timed out Limelog("select() timed out after %d seconds\n", timeoutSec); closeSocket(s); #if defined(LC_WINDOWS) SetLastSocketError(WSAEWOULDBLOCK); #else SetLastSocketError(EWOULDBLOCK); #endif return INVALID_SOCKET; } else if (FD_ISSET(s, &writefds) || FD_ISSET(s, &exceptfds)) { // The socket was signalled SOCKADDR_LEN len = sizeof(err); getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&err, &len); if (err != 0 || FD_ISSET(s, &exceptfds)) { // Get the error code err = (err != 0) ? err : LastSocketFail(); } } // Disable non-blocking I/O now that the connection is established val = 0; ioctlsocket(s, FIONBIO, &val); } #endif if (err != 0) { Limelog("connect() failed: %d\n", err); closeSocket(s); SetLastSocketError(err); return INVALID_SOCKET; } return s; }
void Mud::processNewConnection() { // The file descriptor for the new socket. int socketFileDescriptor; struct sockaddr_in socketAddress; socklen_t socketAddressSize = sizeof(socketAddress); // Loop until all outstanding connections are accepted. while (true) { try { socketFileDescriptor = accept(_servSocket, (struct sockaddr *) &socketAddress, &socketAddressSize); // A bad socket probably means no more connections are outstanding. if (socketFileDescriptor == kNoSocketIndicator) { // blocking is OK - we have accepted all outstanding connections. if (errno == EWOULDBLOCK) { return; } throw std::runtime_error("ACCEPT"); } // Here on successful accept - make sure socket doesn't block. #ifdef __linux__ if (fcntl(socketFileDescriptor, F_SETFL, FNDELAY) == -1) { throw std::runtime_error("FCNTL on player socket"); } #elif __APPLE__ if (fcntl(socketFileDescriptor, F_SETFL, FNDELAY) == -1) { throw std::runtime_error("FCNTL on player socket"); } #elif __CYGWIN__ int flags = fcntl(_servSocket, F_GETFL, 0); //if (fcntl(_servSocket, F_SETFL, flags | O_NONBLOCK | O_RDWR | O_NOCTTY | O_NDELAY) == -1) if (fcntl(_servSocket, F_SETFL, flags | O_NDELAY | O_NONBLOCK) == -1) { throw std::runtime_error("FCNTL on player socket"); } #elif _WIN32 u_long imode = 1; if (ioctlsocket(_servSocket, FIONBIO, &imode) == -1) { throw std::runtime_error("FCNTL on Control Socket"); } #endif std::string address = inet_ntoa(socketAddress.sin_addr); int port = ntohs(socketAddress.sin_port); // Immediately close connections from blocked IP addresses. if (blockedIPs.find(address) != blockedIPs.end()) { Logger::log(LogLevel::Global, "Rejected connection from " + address + "!"); closeSocket(socketFileDescriptor); continue; } Player * player = new Player(socketFileDescriptor, port, address); // Insert the player in the list of players. addPlayer(player); Logger::log(LogLevel::Global, "#--------- New Connection ---------#"); Logger::log(LogLevel::Global, " Socket : " + ToString(socketFileDescriptor)); Logger::log(LogLevel::Global, " Address : " + address); Logger::log(LogLevel::Global, " Port : " + ToString(port)); Logger::log(LogLevel::Global, "#----------------------------------#"); // Activate the procedure of negotiation. NegotiateProtocol(player, ConnectionState::NegotiatingMSDP); } catch (std::exception & e) { Logger::log(LogLevel::Error, "Error during processing a new connection."); Logger::log(LogLevel::Error, "Error : " + std::string(e.what())); break; } } }
void close() { Error error = closeSocket(socket().lowest_layer()); if (error && !core::http::isConnectionTerminatedError(error)) logError(error); }