Addrinfo::Addrinfo(const struct sockaddr* sa) : addr("undefined"), port(-1) { switch (sa->sa_family) { case AF_INET: { char ip_str[INET_ADDRSTRLEN]; struct sockaddr_in* src = (struct sockaddr_in*) sa; int ret = uv_inet_ntop(AF_INET, &src->sin_addr, ip_str, sizeof(ip_str)); if (ret) { LINEAR_LOG(LOG_ERR, "fail inet_ntop: %s", uv_strerror(ret)); } else { addr = std::string(ip_str); port = ntohs(src->sin_port); } break; } case AF_INET6: { char ip_str[INET6_ADDRSTRLEN]; struct sockaddr_in6* src = (struct sockaddr_in6*) sa; int ret = uv_inet_ntop(AF_INET6, &src->sin6_addr, ip_str, sizeof(ip_str)); if (ret) { LINEAR_LOG(LOG_ERR, "fail inet_ntop: %s", uv_strerror(ret)); } else { addr = std::string(ip_str); port = ntohs(src->sin6_port); } break; } default: break; } }
Error TimerImpl::Start(int id, TimerCallback callback, unsigned int timeout, void* args) { linear::lock_guard<linear::mutex> lock(mutex_); if (state_ == START) { return Error(LNR_EALREADY); } tv_timer_ = static_cast<tv_timer_t*>(malloc(sizeof(tv_timer_t))); if (tv_timer_ == NULL) { return Error(LNR_ENOMEM); } int ret = tv_timer_init(EventLoop::GetDefault().GetHandle(), tv_timer_); if (ret) { LINEAR_LOG(LOG_ERR, "fail to start timer: %s", tv_strerror(reinterpret_cast<tv_handle_t*>(tv_timer_), ret)); free(tv_timer_); tv_timer_ = NULL; return Error(ret); } EventLoop::TimerEventData* data = new EventLoop::TimerEventData(id, this); tv_timer_->data = data; state_ = START; callback_ = callback; args_ = args; ret = tv_timer_start(tv_timer_, EventLoop::OnTimer, static_cast<uint64_t>(timeout), 0); if (ret) { LINEAR_LOG(LOG_ERR, "fail to start timer: %s", tv_strerror(reinterpret_cast<tv_handle_t*>(tv_timer_), ret)); state_ = STOP; delete data; free(tv_timer_); tv_timer_ = NULL; return Error(ret); } LINEAR_DEBUG(LOG_DEBUG, "timer = %p, timer->data = %p", tv_timer_, tv_timer_->data); return Error(LNR_OK); }
SSLSocket SSLClient::CreateSocket(const std::string& hostname, int port) { if (client_) { return static_pointer_cast<SSLClientImpl>(client_)->CreateSocket(hostname, port, client_); } LINEAR_LOG(LOG_ERR, "handler is not set"); throw std::invalid_argument("handler is not set"); }
void EventLoopImpl::OnClose(tv_handle_t* handle) { assert(handle != NULL && handle->data != NULL); switch (static_cast<Event*>(handle->data)->type) { case SERVER: { ServerEvent* ev = static_cast<ServerEvent*>(handle->data); delete ev; } break; case SOCKET: { SocketEvent* ev = static_cast<SocketEvent*>(handle->data); if (linear::shared_ptr<SocketImpl> socket = ev->socket.lock()) { socket->OnDisconnect(socket); } delete ev; } break; case TIMER: { TimerEvent* ev = static_cast<TimerEvent*>(handle->data); delete ev; } break; default: LINEAR_LOG(LOG_ERR, "BUG: invalid type of event"); assert(false); } free(handle); }
Error Socket::Disconnect() const { if (!socket_) { return Error(LNR_EBADF); } const linear::Addrinfo& peer = GetPeerInfo(); LINEAR_LOG(LOG_DEBUG, "try to disconnect: %s:%d,%s", peer.addr.c_str(), peer.port, GetTypeString(GetType()).c_str()); return socket_->Disconnect(); }
Error Socket::Disconnect() const { if (!socket_) { return Error(LNR_EBADF); } const linear::Addrinfo& self = GetSelfInfo(); const linear::Addrinfo& peer = GetPeerInfo(); LINEAR_LOG(LOG_DEBUG, "try to disconnect(id = %d): %s:%d x-- %s --- %s:%d", GetId(), (self.proto == Addrinfo::IPv4) ? self.addr.c_str() : (std::string("[" + self.addr + "]")).c_str(), self.port, GetTypeString(GetType()).c_str(), (peer.proto == Addrinfo::IPv4) ? peer.addr.c_str() : (std::string("[" + peer.addr + "]")).c_str(), peer.port); return socket_->Disconnect(); }
Error Socket::Connect(unsigned int timeout) const { if (!socket_) { return Error(LNR_EBADF); } Error e(LNR_ENOMEM); try { EventLoopImpl::SocketEvent* ev = new EventLoopImpl::SocketEvent(socket_); e = socket_->Connect(timeout, ev); if (e != Error(LNR_OK)) { delete ev; } } catch(...) { LINEAR_LOG(LOG_ERR, "no memory"); } return e; }
WSSocket::WSSocket(const shared_ptr<SocketImpl>& socket) : Socket(socket) { if (GetType() != Socket::WS) { LINEAR_LOG(LOG_ERR, "invalid type_cast: type = %d, id = %d", GetType(), GetId()); throw std::bad_cast(); } }