void Simulator::shutdown() { while(!mQueries.empty()) { Querier* query = mQueries.front(); removeQuery(query); delete query; } delete mHandler; mHandler = NULL; SimulatorBase::shutdown(); }
static int dnsTimeoutHandler(TimeEventHandlerPtr event) { DnsQueryPtr query = *(DnsQueryPtr*)event->data; ObjectPtr object = query->object; int rc; /* People are reporting that this does happen. And I have no idea why. */ if(!queryInFlight(query)) { do_log(L_ERROR, "BUG: timing out martian query (%s, flags: 0x%x).\n", scrub(query->name->string), (unsigned)object->flags); return 1; } query->timeout = MAX(10, query->timeout * 2); if(query->timeout > dnsMaxTimeout) { abortObject(object, 501, internAtom("Timeout")); goto fail; } else { rc = sendQuery(query); if(rc < 0) { if(rc != -EWOULDBLOCK && rc != -EAGAIN && rc != -ENOBUFS) { abortObject(object, 501, internAtomError(-rc, "Couldn't send DNS query")); goto fail; } /* else let it timeout */ } query->timeout_handler = scheduleTimeEvent(query->timeout, dnsTimeoutHandler, sizeof(query), &query); if(query->timeout_handler == NULL) { do_log(L_ERROR, "Couldn't schedule DNS timeout handler.\n"); abortObject(object, 501, internAtom("Couldn't schedule DNS timeout handler")); goto fail; } return 1; } fail: removeQuery(query); object->flags &= ~OBJECT_INPROGRESS; if(query->inet4) releaseAtom(query->inet4); if(query->inet6) releaseAtom(query->inet6); free(query); releaseNotifyObject(object); return 1; }
bool ProfileDB::removeAllProfiles() { bool success = false; QSqlQuery removeQuery(QSqlDatabase::database(connectionName)); removeQuery.prepare("DELETE FROM Profiles"); if (removeQuery.exec()) { success = true; } else { //qDebug() << "remove all profiles failed: " << removeQuery.lastError(); } return success; }
void DBItemDAO::remove(BillItem::Ptr item) { qCDebug(lcPersistence) << "Entering DBItemDAO::remove with param " + item->toString(); try { m_validator->validateIdentity(item); } catch (ValidationException *e) { throw new PersistenceException(e); } QSqlQuery removeQuery(m_database); removeQuery.prepare("UPDATE ITEM SET DELETED = 1 WHERE ID = ?;"); removeQuery.addBindValue(item->id()); if (!removeQuery.exec()) { qCCritical(lcPersistence) << "DBItemDAO::remove failed:" + removeQuery.lastError().text(); throw new PersistenceException("DBItemDAO::remove failed:" + removeQuery.lastError().text()); } if (removeQuery.numRowsAffected() == 0) { qCDebug(lcPersistence) << "DBItemDAO::remove failed: dataset not found"; throw new PersistenceException("DBItemDAO::remove failed: dataset not found"); } }
static int really_do_dns(AtomPtr name, ObjectPtr object) { int rc; DnsQueryPtr query; AtomPtr message = NULL; int id; AtomPtr a = NULL; if(a == NULL) { if(name == atomLocalhost || name == atomLocalhostDot) { char s[1 + sizeof(HostAddressRec)]; memset(s, 0, sizeof(s)); s[0] = DNS_A; s[1] = 4; s[2] = 127; s[3] = 0; s[4] = 0; s[5] = 1; a = internAtomN(s, 1 + sizeof(HostAddressRec)); if(a == NULL) { abortObject(object, 501, internAtom("Couldn't allocate address")); notifyObject(object); errno = ENOMEM; return -1; } } } if(a == NULL) { struct in_addr ina; rc = inet_aton(name->string, &ina); if(rc == 1) { char s[1 + sizeof(HostAddressRec)]; memset(s, 0, sizeof(s)); s[0] = DNS_A; s[1] = 4; memcpy(s + 2, &ina, 4); a = internAtomN(s, 1 + sizeof(HostAddressRec)); if(a == NULL) { abortObject(object, 501, internAtom("Couldn't allocate address")); notifyObject(object); errno = ENOMEM; return -1; } } } #ifdef HAVE_IPv6 if(a == NULL) a = rfc2732(name); #endif if(a) { object->headers = a; object->age = current_time.tv_sec; object->expires = current_time.tv_sec + 240; object->flags &= ~(OBJECT_INITIAL | OBJECT_INPROGRESS); notifyObject(object); return 0; } rc = establishDnsSocket(); if(rc < 0) { do_log_error(L_ERROR, -rc, "Couldn't establish DNS socket.\n"); message = internAtomError(-rc, "Couldn't establish DNS socket"); goto fallback; } /* The id is used to speed up detecting replies to queries that are no longer current -- see dnsReplyHandler. */ id = (idSeed++) & 0xFFFF; query = malloc(sizeof(DnsQueryRec)); if(query == NULL) { do_log(L_ERROR, "Couldn't allocate DNS query.\n"); message = internAtom("Couldn't allocate DNS query"); goto fallback; } query->id = id; query->inet4 = NULL; query->inet6 = NULL; query->name = name; query->time = current_time.tv_sec; query->object = retainObject(object); query->timeout = 4; query->timeout_handler = NULL; query->next = NULL; query->timeout_handler = scheduleTimeEvent(query->timeout, dnsTimeoutHandler, sizeof(query), &query); if(query->timeout_handler == NULL) { do_log(L_ERROR, "Couldn't schedule DNS timeout handler.\n"); message = internAtom("Couldn't schedule DNS timeout handler"); goto free_fallback; } insertQuery(query); object->flags |= OBJECT_INPROGRESS; rc = sendQuery(query); if(rc < 0) { if(rc != -EWOULDBLOCK && rc != -EAGAIN && rc != -ENOBUFS) { object->flags &= ~OBJECT_INPROGRESS; message = internAtomError(-rc, "Couldn't send DNS query"); goto remove_fallback; } /* else let it timeout */ } releaseAtom(message); return 1; remove_fallback: removeQuery(query); free_fallback: releaseObject(query->object); cancelTimeEvent(query->timeout_handler); free(query); fallback: if(dnsUseGethostbyname >= 1) { releaseAtom(message); do_log(L_WARN, "Falling back on gethostbyname.\n"); return really_do_gethostbyname(name, object); } else { abortObject(object, 501, message); notifyObject(object); return 1; } }
static int dnsReplyHandler(int abort, FdEventHandlerPtr event) { int fd = event->fd; char buf[2048]; int len, rc; ObjectPtr object; unsigned ttl = 0; AtomPtr name, value, message = NULL; int id; int af; DnsQueryPtr query; AtomPtr cname = NULL; if(abort) { dnsSocketHandler = NULL; rc = establishDnsSocket(); if(rc < 0) { do_log(L_ERROR, "Couldn't reestablish DNS socket.\n"); /* At this point, we should abort all in-flight DNS requests. Oh, well, they'll timeout anyway. */ } return 1; } len = recv(fd, buf, 2048, 0); if(len <= 0) { if(errno == EINTR || errno == EAGAIN) return 0; /* This is where we get ECONNREFUSED for an ICMP port unreachable */ do_log_error(L_ERROR, errno, "DNS: recv failed"); dnsGethostbynameFallback(-1, message); return 0; } /* This could be a late reply to a query that timed out and was resent, a reply to a query that timed out, or a reply to an AAAA query when we already got a CNAME reply to the associated A. We filter such replies straight away, without trying to parse them. */ rc = dnsReplyId(buf, 0, len, &id); if(rc < 0) { do_log(L_WARN, "Short DNS reply.\n"); return 0; } if(!findQuery(id, NULL)) { return 0; } rc = dnsDecodeReply(buf, 0, len, &id, &name, &value, &af, &ttl); if(rc < 0) { assert(value == NULL); /* We only want to fallback on gethostbyname if we received a reply that we could not understand. What about truncated replies? */ if(rc < 0) { do_log_error(L_WARN, -rc, "DNS"); if(dnsUseGethostbyname >= 2 || (dnsUseGethostbyname && (rc != -EDNS_HOST_NOT_FOUND && rc != -EDNS_NO_RECOVERY && rc != -EDNS_FORMAT))) { dnsGethostbynameFallback(id, message); return 0; } else { message = internAtom(pstrerror(-rc)); } } else { assert(name != NULL && id >= 0 && af >= 0); } } query = findQuery(id, name); if(query == NULL) { /* Duplicate id ? */ releaseAtom(value); releaseAtom(name); return 0; } /* We're going to use the information in this reply. If it was an error, construct an empty atom to distinguish it from information we're still waiting for. */ if(value == NULL) value = internAtom(""); again: if(af == 4) { if(query->inet4 == NULL) { query->inet4 = value; query->ttl4 = current_time.tv_sec + ttl; } else releaseAtom(value); } else if(af == 6) { if(query->inet6 == NULL) { query->inet6 = value; query->ttl6 = current_time.tv_sec + ttl; } else releaseAtom(value); } else if(af == 0) { /* Ignore errors in this case. */ if(query->inet4 && query->inet4->length == 0) { releaseAtom(query->inet4); query->inet4 = NULL; } if(query->inet6 && query->inet6->length == 0) { releaseAtom(query->inet6); query->inet6 = NULL; } if(query->inet4 || query->inet6) { do_log(L_WARN, "Host %s has both %s and CNAME -- " "ignoring CNAME.\n", scrub(query->name->string), query->inet4 ? "A" : "AAAA"); releaseAtom(value); value = internAtom(""); af = query->inet4 ? 4 : 6; goto again; } else { cname = value; } } if(rc >= 0 && !cname && ((dnsQueryIPv6 < 3 && query->inet4 == NULL) || (dnsQueryIPv6 > 0 && query->inet6 == NULL))) return 0; /* This query is complete */ cancelTimeEvent(query->timeout_handler); object = query->object; if(object->flags & OBJECT_INITIAL) { assert(!object->headers); if(cname) { assert(query->inet4 == NULL && query->inet6 == NULL); object->headers = cname; object->expires = current_time.tv_sec + ttl; } else if((!query->inet4 || query->inet4->length == 0) && (!query->inet6 || query->inet6->length == 0)) { releaseAtom(query->inet4); releaseAtom(query->inet6); object->expires = current_time.tv_sec + dnsNegativeTtl; abortObject(object, 500, retainAtom(message)); } else if(!query->inet4 || query->inet4->length == 0) { object->headers = query->inet6; object->expires = query->ttl6; releaseAtom(query->inet4); } else if(!query->inet6 || query->inet6->length == 0) { object->headers = query->inet4; object->expires = query->ttl4; releaseAtom(query->inet6); } else { /* need to merge results */ char buf[1024]; if(query->inet4->length + query->inet6->length > 1024) { releaseAtom(query->inet4); releaseAtom(query->inet6); abortObject(object, 500, internAtom("DNS reply too long")); } else { if(dnsQueryIPv6 <= 1) { memcpy(buf, query->inet4->string, query->inet4->length); memcpy(buf + query->inet4->length, query->inet6->string + 1, query->inet6->length - 1); } else { memcpy(buf, query->inet6->string, query->inet6->length); memcpy(buf + query->inet6->length, query->inet4->string + 1, query->inet4->length - 1); } object->headers = internAtomN(buf, query->inet4->length + query->inet6->length - 1); if(object->headers == NULL) abortObject(object, 500, internAtom("Couldn't allocate DNS atom")); } object->expires = MIN(query->ttl4, query->ttl6); } object->age = current_time.tv_sec; object->flags &= ~(OBJECT_INITIAL | OBJECT_INPROGRESS); } else { do_log(L_WARN, "DNS object ex nihilo for %s.\n", scrub(query->name->string)); } removeQuery(query); free(query); releaseAtom(name); releaseAtom(message); releaseNotifyObject(object); return 0; }