123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- // Original author: ekr@rtfm.com
- #include "logging.h"
- #include "nspr.h"
- #include "prerror.h"
- #include "prio.h"
- #include "nsCOMPtr.h"
- #include "nsASocketHandler.h"
- #include "nsISocketTransportService.h"
- #include "nsNetCID.h"
- #include "nsServiceManagerUtils.h"
- #include "nsXPCOM.h"
- #include "transportflow.h"
- #include "transportlayerprsock.h"
- namespace mozilla {
- MOZ_MTLOG_MODULE("mtransport")
- nsresult TransportLayerPrsock::InitInternal() {
- // Get the transport service as a transport service
- nsresult rv;
- stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
- if (!NS_SUCCEEDED(rv)) {
- MOZ_MTLOG(ML_ERROR, "Couldn't get socket transport service");
- return rv;
- }
- return NS_OK;
- }
- void TransportLayerPrsock::Import(PRFileDesc *fd, nsresult *result) {
- if (state_ != TS_INIT) {
- *result = NS_ERROR_NOT_INITIALIZED;
- return;
- }
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Importing()");
- fd_ = fd;
- handler_ = new SocketHandler(this, fd);
- nsresult rv = stservice_->AttachSocket(fd_, handler_);
- if (!NS_SUCCEEDED(rv)) {
- *result = rv;
- return;
- }
- TL_SET_STATE(TS_OPEN);
- *result = NS_OK;
- }
- int TransportLayerPrsock::SendPacket(const unsigned char *data, size_t len) {
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "SendPacket(" << len << ")");
- if (state_ != TS_OPEN) {
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Can't send packet on closed interface");
- return TE_INTERNAL;
- }
- int32_t status;
- status = PR_Write(fd_, data, len);
- if (status >= 0) {
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Wrote " << len << " bytes");
- return status;
- }
- PRErrorCode err = PR_GetError();
- if (err == PR_WOULD_BLOCK_ERROR) {
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Write blocked");
- return TE_WOULDBLOCK;
- }
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Write error; channel closed");
- TL_SET_STATE(TS_ERROR);
- return TE_ERROR;
- }
- void TransportLayerPrsock::OnSocketReady(PRFileDesc *fd, int16_t outflags) {
- if (!(outflags & PR_POLL_READ)) {
- return;
- }
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "OnSocketReady(flags=" << outflags << ")");
- unsigned char buf[1600];
- int32_t rv = PR_Read(fd, buf, sizeof(buf));
- if (rv > 0) {
- // Successful read
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read " << rv << " bytes");
- SignalPacketReceived(this, buf, rv);
- } else if (rv == 0) {
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read 0 bytes; channel closed");
- TL_SET_STATE(TS_CLOSED);
- } else {
- PRErrorCode err = PR_GetError();
- if (err != PR_WOULD_BLOCK_ERROR) {
- MOZ_MTLOG(ML_DEBUG, LAYER_INFO << "Read error; channel closed");
- TL_SET_STATE(TS_ERROR);
- }
- }
- }
- NS_IMPL_ISUPPORTS0(TransportLayerPrsock::SocketHandler)
- } // close namespace
|