merge mozilla-inbound to mozilla-central

This commit is contained in:
Carsten "Tomcat" Book 2014-03-12 12:15:34 +01:00
commit 9325b1542c
111 changed files with 3552 additions and 2789 deletions

View File

@ -1036,6 +1036,7 @@ var gBrowserInit = {
gFormSubmitObserver.init();
SocialUI.init();
gRemoteTabsUI.init();
gPageStyleMenu.init();
// Initialize the full zoom setting.
// We do this before the session restore service gets initialized so we can
@ -1092,12 +1093,9 @@ var gBrowserInit = {
if (!getBoolPref("ui.click_hold_context_menus", false))
SetClickAndHoldHandlers();
// Bug 666804 - NetworkPrioritizer support for e10s
if (!gMultiProcessBrowser) {
let NP = {};
Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
NP.trackBrowserWindow(window);
}
let NP = {};
Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
NP.trackBrowserWindow(window);
PlacesToolbarHelper.init();
@ -3497,15 +3495,17 @@ var XULBrowserWindow = {
const nsIWebProgressListener = Ci.nsIWebProgressListener;
const nsIChannel = Ci.nsIChannel;
let browser = gBrowser.selectedBrowser;
if (aStateFlags & nsIWebProgressListener.STATE_START &&
aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
if (aRequest && aWebProgress.isTopLevel) {
// clear out feed data
gBrowser.selectedBrowser.feeds = null;
browser.feeds = null;
// clear out search-engine data
gBrowser.selectedBrowser.engines = null;
browser.engines = null;
}
this.isBusy = true;
@ -3546,7 +3546,7 @@ var XULBrowserWindow = {
this.setDefaultStatus(msg);
// Disable menu entries for images, enable otherwise
if (!gMultiProcessBrowser && content.document && mimeTypeIsTextBased(content.document.contentType))
if (browser.documentContentType && mimeTypeIsTextBased(browser.documentContentType))
this.isImage.removeAttribute('disabled');
else
this.isImage.setAttribute('disabled', 'true');
@ -3590,8 +3590,10 @@ var XULBrowserWindow = {
}
}
let browser = gBrowser.selectedBrowser;
// Disable menu entries for images, enable otherwise
if (!gMultiProcessBrowser && content.document && mimeTypeIsTextBased(content.document.contentType))
if (browser.documentContentType && mimeTypeIsTextBased(browser.documentContentType))
this.isImage.removeAttribute('disabled');
else
this.isImage.setAttribute('disabled', 'true');
@ -3605,7 +3607,6 @@ var XULBrowserWindow = {
// Update urlbar only if a new page was loaded on the primary content area
// Do not update urlbar if there was a subframe navigation
var browser = gBrowser.selectedBrowser;
if (aWebProgress.isTopLevel) {
if ((location == "about:blank" && (gMultiProcessBrowser || !content.opener)) ||
location == "") { // Second condition is for new tabs, otherwise
@ -5199,39 +5200,54 @@ function charsetLoadListener() {
var gPageStyleMenu = {
_getAllStyleSheets: function (frameset) {
var styleSheetsArray = Array.slice(frameset.document.styleSheets);
for (let i = 0; i < frameset.frames.length; i++) {
let frameSheets = this._getAllStyleSheets(frameset.frames[i]);
styleSheetsArray = styleSheetsArray.concat(frameSheets);
// This maps from a <browser> element (or, more specifically, a
// browser's permanentKey) to a CPOW that gives synchronous access
// to the list of style sheets in a content window. The use of the
// permanentKey is to avoid issues with docshell swapping.
_pageStyleSyncHandlers: new WeakMap(),
init: function() {
let mm = window.messageManager;
mm.addMessageListener("PageStyle:SetSyncHandler", (msg) => {
this._pageStyleSyncHandlers.set(msg.target.permanentKey, msg.objects.syncHandler);
});
},
getAllStyleSheets: function () {
let handler = this._pageStyleSyncHandlers.get(gBrowser.selectedBrowser.permanentKey);
try {
return handler.getAllStyleSheets();
} catch (ex) {
// In case the child died or timed out.
return [];
}
},
_getStyleSheetInfo: function (browser) {
let handler = this._pageStyleSyncHandlers.get(gBrowser.selectedBrowser.permanentKey);
try {
return handler.getStyleSheetInfo();
} catch (ex) {
// In case the child died or timed out.
return {styleSheets: [], authorStyleDisabled: false, preferredStyleSheetSet: true};
}
return styleSheetsArray;
},
fillPopup: function (menuPopup) {
let styleSheetInfo = this._getStyleSheetInfo(gBrowser.selectedBrowser);
var noStyle = menuPopup.firstChild;
var persistentOnly = noStyle.nextSibling;
var sep = persistentOnly.nextSibling;
while (sep.nextSibling)
menuPopup.removeChild(sep.nextSibling);
var styleSheets = this._getAllStyleSheets(window.content);
let styleSheets = styleSheetInfo.styleSheets;
var currentStyleSheets = {};
var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
var styleDisabled = styleSheetInfo.authorStyleDisabled;
var haveAltSheets = false;
var altStyleSelected = false;
for (let currentStyleSheet of styleSheets) {
if (!currentStyleSheet.title)
continue;
// Skip any stylesheets whose media attribute doesn't match.
if (currentStyleSheet.media.length > 0) {
let mediaQueryList = currentStyleSheet.media.mediaText;
if (!window.content.matchMedia(mediaQueryList).matches)
continue;
}
if (!currentStyleSheet.disabled)
altStyleSelected = true;
@ -5257,51 +5273,29 @@ var gPageStyleMenu = {
noStyle.setAttribute("checked", styleDisabled);
persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
persistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? haveAltSheets : false;
persistentOnly.hidden = styleSheetInfo.preferredStyleSheetSet ? haveAltSheets : false;
sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
},
_stylesheetInFrame: function (frame, title) {
return Array.some(frame.document.styleSheets,
function (stylesheet) stylesheet.title == title);
},
_stylesheetSwitchFrame: function (frame, title) {
var docStyleSheets = frame.document.styleSheets;
for (let i = 0; i < docStyleSheets.length; ++i) {
let docStyleSheet = docStyleSheets[i];
if (docStyleSheet.title)
docStyleSheet.disabled = (docStyleSheet.title != title);
else if (docStyleSheet.disabled)
docStyleSheet.disabled = false;
}
},
_stylesheetSwitchAll: function (frameset, title) {
if (!title || this._stylesheetInFrame(frameset, title))
this._stylesheetSwitchFrame(frameset, title);
for (let i = 0; i < frameset.frames.length; i++)
this._stylesheetSwitchAll(frameset.frames[i], title);
},
switchStyleSheet: function (title, contentWindow) {
getMarkupDocumentViewer().authorStyleDisabled = false;
this._stylesheetSwitchAll(contentWindow || content, title);
switchStyleSheet: function (title) {
let mm = gBrowser.selectedBrowser.messageManager;
mm.sendAsyncMessage("PageStyle:Switch", {title: title});
},
disableStyle: function () {
getMarkupDocumentViewer().authorStyleDisabled = true;
let mm = gBrowser.selectedBrowser.messageManager;
mm.sendAsyncMessage("PageStyle:Disable");
},
};
/* Legacy global page-style functions */
var getAllStyleSheets = gPageStyleMenu._getAllStyleSheets.bind(gPageStyleMenu);
var getAllStyleSheets = gPageStyleMenu.getAllStyleSheets.bind(gPageStyleMenu);
var stylesheetFillPopup = gPageStyleMenu.fillPopup.bind(gPageStyleMenu);
function stylesheetSwitchAll(contentWindow, title) {
gPageStyleMenu.switchStyleSheet(title, contentWindow);
// We ignore the contentWindow param. Add-ons don't appear to use
// it, and it's difficult to support in e10s (where it will be a
// CPOW).
gPageStyleMenu.switchStyleSheet(title);
}
function setStyleDisabled(disabled) {
if (disabled)

View File

@ -290,3 +290,99 @@ ContentLinkHandler.init(this);
addEventListener("DOMWebNotificationClicked", function(event) {
sendAsyncMessage("DOMWebNotificationClicked", {});
}, false);
let PageStyleHandler = {
init: function() {
addMessageListener("PageStyle:Switch", this);
addMessageListener("PageStyle:Disable", this);
// Send a CPOW to the parent so that it can synchronously request
// the list of style sheets.
sendSyncMessage("PageStyle:SetSyncHandler", {}, {syncHandler: this});
},
get markupDocumentViewer() {
return docShell.contentViewer.QueryInterface(Ci.nsIMarkupDocumentViewer);
},
// Called synchronously via CPOW from the parent.
getStyleSheetInfo: function() {
let styleSheets = this._filterStyleSheets(this.getAllStyleSheets());
return {
styleSheets: styleSheets,
authorStyleDisabled: this.markupDocumentViewer.authorStyleDisabled,
preferredStyleSheetSet: content.document.preferredStyleSheetSet
};
},
// Called synchronously via CPOW from the parent.
getAllStyleSheets: function(frameset = content) {
let selfSheets = Array.slice(frameset.document.styleSheets);
let subSheets = Array.map(frameset.frames, frame => this.getAllStyleSheets(frame));
return selfSheets.concat(...subSheets);
},
receiveMessage: function(msg) {
switch (msg.name) {
case "PageStyle:Switch":
this.markupDocumentViewer.authorStyleDisabled = false;
this._stylesheetSwitchAll(content, msg.data.title);
break;
case "PageStyle:Disable":
this.markupDocumentViewer.authorStyleDisabled = true;
break;
}
},
_stylesheetSwitchAll: function (frameset, title) {
if (!title || this._stylesheetInFrame(frameset, title)) {
this._stylesheetSwitchFrame(frameset, title);
}
for (let i = 0; i < frameset.frames.length; i++) {
// Recurse into sub-frames.
this._stylesheetSwitchAll(frameset.frames[i], title);
}
},
_stylesheetSwitchFrame: function (frame, title) {
var docStyleSheets = frame.document.styleSheets;
for (let i = 0; i < docStyleSheets.length; ++i) {
let docStyleSheet = docStyleSheets[i];
if (docStyleSheet.title) {
docStyleSheet.disabled = (docStyleSheet.title != title);
} else if (docStyleSheet.disabled) {
docStyleSheet.disabled = false;
}
}
},
_stylesheetInFrame: function (frame, title) {
return Array.some(frame.document.styleSheets, (styleSheet) => styleSheet.title == title);
},
_filterStyleSheets: function(styleSheets) {
let result = [];
for (let currentStyleSheet of styleSheets) {
if (!currentStyleSheet.title)
continue;
// Skip any stylesheets that don't match the screen media type.
if (currentStyleSheet.media.length > 0) {
let mediaQueryList = currentStyleSheet.media.mediaText;
if (!content.matchMedia(mediaQueryList).matches) {
continue;
}
}
result.push({title: currentStyleSheet.title,
disabled: currentStyleSheet.disabled});
}
return result;
},
};
PageStyleHandler.init();

View File

@ -80,18 +80,12 @@ let BrowserHelper = {
windowEntry.lastSelectedBrowser = aBrowser;
},
// Auxiliary methods
getLoadgroup: function NP_BH_getLoadgroup(aBrowser) {
return aBrowser.webNavigation.QueryInterface(Ci.nsIDocumentLoader)
.loadGroup.QueryInterface(Ci.nsISupportsPriority);
},
increasePriority: function NP_BH_increasePriority(aBrowser) {
this.getLoadgroup(aBrowser).adjustPriority(PRIORITY_DELTA);
aBrowser.adjustPriority(PRIORITY_DELTA);
},
decreasePriority: function NP_BH_decreasePriority(aBrowser) {
this.getLoadgroup(aBrowser).adjustPriority(PRIORITY_DELTA * -1);
aBrowser.adjustPriority(PRIORITY_DELTA * -1);
}
};

View File

@ -105,7 +105,7 @@ class MachCommands(MachCommandBase):
'--smc-check=all-non-file',
'--vex-iropt-register-updates=allregs-at-mem-access',
'--gen-suppressions=all',
'--num-callers=20',
'--num-callers=36',
'--leak-check=full',
'--show-possibly-lost=no',
'--track-origins=yes'

View File

@ -96,6 +96,17 @@ WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, GLenum target, GLin
mRenderbufferPtr = nullptr;
mTexImageTarget = target;
mTexImageLevel = level;
mNeedsFinalize = true;
}
void
WebGLFramebuffer::Attachment::SetRenderbuffer(WebGLRenderbuffer* rb)
{
mTexturePtr = nullptr;
mRenderbufferPtr = rb;
mNeedsFinalize = true;
}
bool
@ -315,12 +326,31 @@ WebGLFramebuffer::Attachment::IsComplete() const
}
void
WebGLFramebuffer::Attachment::FinalizeAttachment(GLenum attachmentLoc) const
WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmentLoc) const
{
if (!mNeedsFinalize)
return;
mNeedsFinalize = false;
if (!HasImage()) {
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, 0);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, 0);
} else {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
LOCAL_GL_RENDERBUFFER, 0);
}
return;
}
MOZ_ASSERT(HasImage());
if (Texture()) {
GLContext* gl = Texture()->Context()->gl;
MOZ_ASSERT(gl == Texture()->Context()->gl);
if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
TexImageTarget(), Texture()->GLName(), TexImageLevel());
@ -832,22 +862,18 @@ FinalizeDrawAndReadBuffers(GLContext* aGL, bool aColorBufferDefined)
void
WebGLFramebuffer::FinalizeAttachments() const
{
GLContext* gl = mContext->gl;
size_t count = ColorAttachmentCount();
for (size_t i = 0; i < count; i++) {
if (ColorAttachment(i).IsDefined())
ColorAttachment(i).FinalizeAttachment(LOCAL_GL_COLOR_ATTACHMENT0 + i);
ColorAttachment(i).FinalizeAttachment(gl, LOCAL_GL_COLOR_ATTACHMENT0 + i);
}
if (DepthAttachment().IsDefined())
DepthAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_ATTACHMENT);
DepthAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_ATTACHMENT);
StencilAttachment().FinalizeAttachment(gl, LOCAL_GL_STENCIL_ATTACHMENT);
DepthStencilAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
if (StencilAttachment().IsDefined())
StencilAttachment().FinalizeAttachment(LOCAL_GL_STENCIL_ATTACHMENT);
if (DepthStencilAttachment().IsDefined())
DepthStencilAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
FinalizeDrawAndReadBuffers(mContext->gl, ColorAttachment(0).IsDefined());
FinalizeDrawAndReadBuffers(gl, ColorAttachment(0).IsDefined());
}
inline void

View File

@ -41,9 +41,11 @@ public:
GLenum mAttachmentPoint;
GLenum mTexImageTarget;
GLint mTexImageLevel;
mutable bool mNeedsFinalize;
Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0)
: mAttachmentPoint(aAttachmentPoint)
, mNeedsFinalize(false)
{}
bool IsDefined() const {
@ -56,10 +58,8 @@ public:
bool IsReadableFloat() const;
void SetTexImage(WebGLTexture* tex, GLenum target, GLint level);
void SetRenderbuffer(WebGLRenderbuffer* rb) {
mTexturePtr = nullptr;
mRenderbufferPtr = rb;
}
void SetRenderbuffer(WebGLRenderbuffer* rb);
const WebGLTexture* Texture() const {
return mTexturePtr;
}
@ -92,7 +92,7 @@ public:
bool HasImage() const;
bool IsComplete() const;
void FinalizeAttachment(GLenum attachmentLoc) const;
void FinalizeAttachment(gl::GLContext* gl, GLenum attachmentLoc) const;
};
void Delete();

View File

@ -142,6 +142,24 @@ public:
return mContentType;
}
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
// Not owned:
// - mBuffer
// - mPrincipal
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mContentType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
return size;
}
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
const uint8_t * mBuffer;
uint32_t mLength;

View File

@ -386,6 +386,28 @@ MediaCacheStream::MediaCacheStream(ChannelMediaResource* aClient)
{
}
size_t MediaCacheStream::SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const
{
// Looks like these are not owned:
// - mClient
// - mPrincipal
size_t size = mBlocks.SizeOfExcludingThis(aMallocSizeOf);
size += mReadaheadBlocks.SizeOfExcludingThis(aMallocSizeOf);
size += mMetadataBlocks.SizeOfExcludingThis(aMallocSizeOf);
size += mPlayedBlocks.SizeOfExcludingThis(aMallocSizeOf);
size += mPartialBlockBuffer.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
size_t MediaCacheStream::BlockList::SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const
{
return mEntries.SizeOfExcludingThis(/* sizeOfEntryExcludingThis = */ nullptr,
aMallocSizeOf);
}
void MediaCacheStream::BlockList::AddFirstBlock(int32_t aBlock)
{
NS_ASSERTION(!mEntries.GetEntry(aBlock), "Block already in list");

View File

@ -342,6 +342,9 @@ public:
// 'Read' for argument and return details.
nsresult ReadAt(int64_t aOffset, char* aBuffer,
uint32_t aCount, uint32_t* aBytes);
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
private:
friend class MediaCache;
@ -385,6 +388,8 @@ private:
void Verify() {}
#endif
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
struct Entry : public nsUint32HashKey {
Entry(KeyTypePointer aKey) : nsUint32HashKey(aKey) { }

View File

@ -59,6 +59,8 @@ class MediaMemoryTracker : public nsIMemoryReporter
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
MediaMemoryTracker();
virtual ~MediaMemoryTracker();
void InitMemoryReporter();
@ -1830,10 +1832,16 @@ MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData)
{
int64_t video = 0, audio = 0;
size_t resources = 0;
DecodersArray& decoders = Decoders();
for (size_t i = 0; i < decoders.Length(); ++i) {
video += decoders[i]->VideoQueueMemoryInUse();
audio += decoders[i]->SizeOfAudioQueue();
MediaDecoder* decoder = decoders[i];
video += decoder->VideoQueueMemoryInUse();
audio += decoder->SizeOfAudioQueue();
if (decoder->GetResource()) {
resources += decoder->GetResource()->SizeOfIncludingThis(MallocSizeOf);
}
}
#define REPORT(_path, _amount, _desc) \
@ -1845,12 +1853,16 @@ MediaMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
NS_ENSURE_SUCCESS(rv, rv); \
} while (0)
REPORT("explicit/media/decoded-video", video,
REPORT("explicit/media/decoded/video", video,
"Memory used by decoded video frames.");
REPORT("explicit/media/decoded-audio", audio,
REPORT("explicit/media/decoded/audio", audio,
"Memory used by decoded audio chunks.");
REPORT("explicit/media/resources", resources,
"Memory used by media resources including streaming buffers, caches, "
"etc.");
return NS_OK;
}

View File

@ -1248,6 +1248,20 @@ public:
nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges);
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
// Might be useful to track in the future:
// - mInput
return BaseMediaResource::SizeOfExcludingThis(aMallocSizeOf);
}
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
// These Unsafe variants of Read and Seek perform their operations
// without acquiring mLock. The caller must obtain the lock before

View File

@ -393,6 +393,14 @@ public:
return false;
}
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
return 0;
}
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
virtual ~MediaResource() {};
@ -405,6 +413,26 @@ public:
virtual nsIURI* URI() const { return mURI; }
virtual void MoveLoadsToBackground();
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
// Might be useful to track in the future:
// - mChannel
// - mURI (possibly owned, looks like just a ref from mChannel)
// Not owned:
// - mDecoder
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mContentType.SizeOfIncludingThisIfUnshared(aMallocSizeOf);
return size;
}
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
protected:
BaseMediaResource(MediaDecoder* aDecoder,
nsIChannel* aChannel,
@ -556,6 +584,24 @@ public:
virtual bool IsSuspended();
virtual bool IsTransportSeekable() MOZ_OVERRIDE;
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE {
// Might be useful to track in the future:
// - mListener (seems minor)
// - mChannelStatistics (seems minor)
// owned if RecordStatisticsTo is not called
// - mDataReceivedEvent (seems minor)
size_t size = BaseMediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mCacheStream.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
class Listener MOZ_FINAL : public nsIStreamListener,
public nsIInterfaceRequestor,
public nsIChannelEventSink

View File

@ -1144,6 +1144,19 @@ MediaStreamGraphImpl::ResumeAllAudioOutputs()
}
}
struct AutoProfilerUnregisterThread
{
// The empty ctor is used to silence a pre-4.8.0 GCC unused variable warning.
AutoProfilerUnregisterThread()
{
}
~AutoProfilerUnregisterThread()
{
profiler_unregister_thread();
}
};
void
MediaStreamGraphImpl::RunThread()
{
@ -1156,6 +1169,7 @@ MediaStreamGraphImpl::RunThread()
"Shouldn't have started a graph with empty message queue!");
uint32_t ticksProcessed = 0;
AutoProfilerUnregisterThread autoUnregister;
for (;;) {
// Update mCurrentTime to the min of the playing audio times, or using the
@ -1320,8 +1334,6 @@ MediaStreamGraphImpl::RunThread()
messageQueue.SwapElements(mMessageQueue);
}
}
profiler_unregister_thread();
}
void

View File

@ -69,6 +69,17 @@ public:
MOZ_COUNT_DTOR(RtspTrackBuffer);
mRingBuffer = nullptr;
};
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
// including this
size_t size = aMallocSizeOf(this);
// excluding this
size += mRingBuffer.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
void Start() {
MonitorAutoLock monitor(mMonitor);
mIsStarted = true;
@ -369,6 +380,23 @@ RtspMediaResource::~RtspMediaResource()
}
}
size_t
RtspMediaResource::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t size = BaseMediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mTrackBuffer.SizeOfExcludingThis(aMallocSizeOf);
// Include the size of each track buffer.
for (size_t i = 0; i < mTrackBuffer.Length(); i++) {
size += mTrackBuffer[i]->SizeOfIncludingThis(aMallocSizeOf);
}
// Could add in the future:
// - mMediaStreamController
return size;
}
NS_IMPL_ISUPPORTS2(RtspMediaResource::Listener,
nsIInterfaceRequestor, nsIStreamingProtocolListener);

View File

@ -185,6 +185,14 @@ public:
return NS_ERROR_FAILURE;
}
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
// Listener implements nsIStreamingProtocolListener as
// mMediaStreamController's callback function.
// It holds RtspMediaResource reference to notify the connection status and

View File

@ -133,6 +133,21 @@ public:
virtual bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
virtual const nsCString& GetContentType() const MOZ_OVERRIDE { return mType; }
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
return size;
}
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
const nsAutoCString mType;
};

View File

@ -52,6 +52,16 @@ private:
mData.AppendElements(aData, aSize);
}
nsTArray<uint8_t> mData;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
// size including this
size_t size = aMallocSizeOf(this);
// size excluding this
size += mData.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
};
class ResourceQueueDeallocator : public nsDequeFunctor {
@ -175,6 +185,20 @@ private:
}
return evicted;
}
size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
// Calculate the size of the internal deque.
size_t size = nsDeque::SizeOfExcludingThis(aMallocSizeOf);
// Sum the ResourceItems.
for (int32_t i = 0; i < nsDeque::GetSize(); ++i) {
const ResourceItem* item =
static_cast<const ResourceItem*>(nsDeque::ObjectAt(i));
size += item->SizeOfIncludingThis(aMallocSizeOf);
}
return size;
}
};
public:
@ -226,6 +250,26 @@ public:
virtual const nsCString& GetContentType() const MOZ_OVERRIDE { return mType; }
virtual size_t SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
ReentrantMonitorAutoEnter mon(mMonitor);
// Not owned:
// - mPrincipal
size_t size = MediaResource::SizeOfExcludingThis(aMallocSizeOf);
size += mType.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
size += mInputBuffer.SizeOfExcludingThis(aMallocSizeOf);
return size;
}
virtual size_t SizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
// Used by SourceBuffer.
void AppendData(const uint8_t* aData, uint32_t aLength);
void Ended();
@ -244,7 +288,7 @@ private:
// Protects all of the member variables below. Read() will await a
// Notify() (from Seek, AppendData, Ended, or Close) when insufficient
// data is available in mData.
ReentrantMonitor mMonitor;
mutable ReentrantMonitor mMonitor;
// The buffer holding resource data is a queue of ResourceItem's.
ResourceQueue mInputBuffer;

View File

@ -22,6 +22,14 @@ OggWriter::OggWriter() : ContainerWriter()
}
}
OggWriter::~OggWriter()
{
if (mInitialized) {
ogg_stream_clear(&mOggStreamState);
}
// mPacket's data was always owned by us, no need to ogg_packet_clear.
}
nsresult
OggWriter::Init()
{

View File

@ -22,6 +22,7 @@ class OggWriter : public ContainerWriter
{
public:
OggWriter();
~OggWriter();
nsresult WriteEncodedTrack(const EncodedFrameContainer &aData,
uint32_t aFlags = 0) MOZ_OVERRIDE;

View File

@ -287,6 +287,7 @@ TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t
, mUpdateHitRegion(false)
, mContextMenuHandled(false)
, mWaitingTouchListeners(false)
, mIgnoreKeyPressEvent(false)
{
if (!sActiveDurationMsSet) {
Preferences::AddIntVarCache(&sActiveDurationMs,
@ -1910,8 +1911,19 @@ TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
bool
TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event)
{
// If content code called preventDefault() on a keydown event, then we don't
// want to process any following keypress events.
if (event.message == NS_KEY_PRESS && mIgnoreKeyPressEvent) {
return true;
}
WidgetKeyboardEvent localEvent(event);
DispatchWidgetEvent(localEvent);
nsEventStatus status = DispatchWidgetEvent(localEvent);
if (event.message == NS_KEY_DOWN) {
mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
}
return true;
}

View File

@ -508,6 +508,8 @@ private:
bool mWaitingTouchListeners;
void FireSingleTapEvent(LayoutDevicePoint aPoint);
bool mIgnoreKeyPressEvent;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

View File

@ -17,6 +17,7 @@
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
#include "nsRegion.h"
#include <vector>
#include "mozilla/WidgetUtils.h"
/**
* Different elements of a web pages are rendered into separate "layers" before
@ -201,6 +202,7 @@ public:
: mCompositorID(0)
, mDiagnosticTypes(DIAGNOSTIC_NONE)
, mParent(aParent)
, mScreenRotation(ROTATION_0)
{
MOZ_COUNT_CTOR(Compositor);
}
@ -480,6 +482,30 @@ public:
return nullptr;
}
ScreenRotation GetScreenRotation() const {
return mScreenRotation;
}
void SetScreenRotation(ScreenRotation aRotation) {
mScreenRotation = aRotation;
}
// On b2g the clip rect is in the coordinate space of the physical screen
// independently of its rotation, while the coordinate space of the layers,
// on the other hand, depends on the screen orientation.
// This only applies to b2g as with other platforms, orientation is handled
// at the OS level rather than in Gecko.
gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const {
switch (mScreenRotation) {
case ROTATION_90:
case ROTATION_270:
return gfx::Rect(aClip.y, aClip.x, aClip.height, aClip.width);
case ROTATION_0:
case ROTATION_180:
default:
return aClip;
}
}
protected:
void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
const gfx::Rect& aVisibleRect,
@ -505,6 +531,8 @@ protected:
size_t mPixelsPerFrame;
size_t mPixelsFilled;
ScreenRotation mScreenRotation;
private:
static LayersBackend sBackend;

View File

@ -281,57 +281,6 @@ ImageContainer::LockCurrentImage()
return retval.forget();
}
already_AddRefed<gfxASurface>
ImageContainer::DeprecatedLockCurrentAsSurface(gfx::IntSize *aSize, Image** aCurrentImage)
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
if (mRemoteData) {
NS_ASSERTION(mRemoteDataMutex, "Should have remote data mutex when having remote data!");
mRemoteDataMutex->Lock();
EnsureActiveImage();
if (aCurrentImage) {
NS_IF_ADDREF(mActiveImage);
*aCurrentImage = mActiveImage.get();
}
if (!mActiveImage) {
return nullptr;
}
if (mActiveImage->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP) {
nsRefPtr<gfxImageSurface> newSurf =
new gfxImageSurface(mRemoteData->mBitmap.mData,
ThebesIntSize(mRemoteData->mSize),
mRemoteData->mBitmap.mStride,
mRemoteData->mFormat == RemoteImageData::BGRX32 ?
gfxImageFormat::ARGB32 :
gfxImageFormat::RGB24);
*aSize = newSurf->GetSize().ToIntSize();
return newSurf.forget();
}
*aSize = mActiveImage->GetSize();
return mActiveImage->DeprecatedGetAsSurface();
}
if (aCurrentImage) {
NS_IF_ADDREF(mActiveImage);
*aCurrentImage = mActiveImage.get();
}
if (!mActiveImage) {
return nullptr;
}
*aSize = mActiveImage->GetSize();
return mActiveImage->DeprecatedGetAsSurface();
}
TemporaryRef<gfx::SourceSurface>
ImageContainer::LockCurrentAsSourceSurface(gfx::IntSize *aSize, Image** aCurrentImage)
{

View File

@ -522,17 +522,6 @@ public:
*/
already_AddRefed<gfxASurface> DeprecatedGetCurrentAsSurface(gfx::IntSize* aSizeResult);
/**
* This is similar to GetCurrentAsSurface, however this does not make a copy
* of the image data and requires the user to call UnlockCurrentImage when
* done with the image data. Once UnlockCurrentImage has been called the
* surface returned by this function is no longer valid! This works for any
* type of image. Optionally a pointer can be passed to receive the current
* image.
*/
already_AddRefed<gfxASurface> DeprecatedLockCurrentAsSurface(gfx::IntSize* aSizeResult,
Image** aCurrentImage = nullptr);
/**
* Same as GetCurrentAsSurface but for Moz2D
*/

View File

@ -1308,6 +1308,13 @@ public:
*/
void LogSelf(const char* aPrefix="");
// Print interesting information about this into aTo. Internally
// used to implement Dump*() and Log*(). If subclasses have
// additional interesting properties, they should override this with
// an implementation that first calls the base implementation then
// appends additional info to aTo.
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
/**
@ -1351,13 +1358,6 @@ public:
protected:
Layer(LayerManager* aManager, void* aImplData);
// Print interesting information about this into aTo. Internally
// used to implement Dump*() and Log*(). If subclasses have
// additional interesting properties, they should override this with
// an implementation that first calls the base implementation then
// appends additional info to aTo.
virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
/**
* We can snap layer transforms for two reasons:
* 1) To avoid unnecessary resampling when a transform is a translation

View File

@ -403,7 +403,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent,
// then null it out so we don't keep a dangling reference and leak things.
if (mTouchCount == 0) {
mApzcForInputBlock = nullptr;
mOverscrollHandoffChain.clear();
ClearOverscrollHandoffChain();
}
}
break;
@ -517,7 +517,7 @@ APZCTreeManager::ProcessTouchEvent(WidgetTouchEvent& aEvent,
}
if (mTouchCount == 0) {
mApzcForInputBlock = nullptr;
mOverscrollHandoffChain.clear();
ClearOverscrollHandoffChain();
}
}
return ret;
@ -677,18 +677,58 @@ APZCTreeManager::ClearTree()
mRootApzc = nullptr;
}
/**
* Transform a displacement from the screen coordinates of a source APZC to
* the screen coordinates of a target APZC.
* @param aTreeManager the tree manager for the APZC tree containing |aSource|
* and |aTarget|
* @param aSource the source APZC
* @param aTarget the target APZC
* @param aStartPoint the start point of the displacement
* @param aEndPoint the end point of the displacement
*/
static void
TransformDisplacement(APZCTreeManager* aTreeManager,
AsyncPanZoomController* aSource,
AsyncPanZoomController* aTarget,
ScreenPoint& aStartPoint,
ScreenPoint& aEndPoint) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko; // ignored
// Convert start and end points to untransformed screen coordinates.
aTreeManager->GetInputTransforms(aSource, transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc.Inverse());
ApplyTransform(&aEndPoint, transformToApzc.Inverse());
// Convert start and end points to aTarget's transformed screen coordinates.
aTreeManager->GetInputTransforms(aTarget, transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc);
ApplyTransform(&aEndPoint, transformToApzc);
}
void
APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev, ScreenPoint aStartPoint, ScreenPoint aEndPoint,
uint32_t aOverscrollHandoffChainIndex)
{
// If we have reached the end of the overscroll handoff chain, there is
// nothing more to scroll, so we ignore the rest of the pan gesture.
if (aOverscrollHandoffChainIndex >= mOverscrollHandoffChain.length()) {
// Nothing more to scroll - ignore the rest of the pan gesture.
return;
nsRefPtr<AsyncPanZoomController> next;
{
// Grab tree lock to protect mOverscrollHandoffChain from concurrent
// access from the input and compositor threads.
// Release it before calling TransformDisplacement() as that grabs the
// lock itself.
MonitorAutoLock lock(mTreeLock);
// If we have reached the end of the overscroll handoff chain, there is
// nothing more to scroll, so we ignore the rest of the pan gesture.
if (aOverscrollHandoffChainIndex >= mOverscrollHandoffChain.length()) {
// Nothing more to scroll - ignore the rest of the pan gesture.
return;
}
next = mOverscrollHandoffChain[aOverscrollHandoffChainIndex];
}
nsRefPtr<AsyncPanZoomController> next = mOverscrollHandoffChain[aOverscrollHandoffChainIndex];
if (next == nullptr)
return;
@ -698,18 +738,7 @@ APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev, ScreenPoint aStar
// scroll grabbing to grab the scroll from it), don't bother doing the
// transformations in that case.
if (next != aPrev) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko; // ignored
// Convert start and end points to untransformed screen coordinates.
GetInputTransforms(aPrev, transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc.Inverse());
ApplyTransform(&aEndPoint, transformToApzc.Inverse());
// Convert start and end points to next's transformed screen coordinates.
GetInputTransforms(next, transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc);
ApplyTransform(&aEndPoint, transformToApzc);
TransformDisplacement(this, aPrev, next, aStartPoint, aEndPoint);
}
// Scroll |next|. If this causes overscroll, it will call DispatchScroll()
@ -717,9 +746,69 @@ APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev, ScreenPoint aStar
next->AttemptScroll(aStartPoint, aEndPoint, aOverscrollHandoffChainIndex);
}
void
APZCTreeManager::HandOffFling(AsyncPanZoomController* aPrev, ScreenPoint aVelocity)
{
// Build the overscroll handoff chain. This is necessary because it is
// otherwise built on touch-start and cleared on touch-end, and a fling
// happens after touch-end. Note that, unlike DispatchScroll() which is
// called on every touch-move during overscroll panning,
// HandleFlingOverscroll() is only called once during a fling handoff,
// so it's not worth trying to avoid building the handoff chain here.
BuildOverscrollHandoffChain(aPrev);
nsRefPtr<AsyncPanZoomController> next; // will be used outside monitor block
{
// Grab tree lock to protect mOverscrollHandoffChain from concurrent
// access from the input and compositor threads.
// Release it before calling GetInputTransforms() as that grabs the
// lock itself.
MonitorAutoLock lock(mTreeLock);
// Find |aPrev| in the handoff chain.
uint32_t i;
for (i = 0; i < mOverscrollHandoffChain.length(); ++i) {
if (mOverscrollHandoffChain[i] == aPrev) {
break;
}
}
// Get the next APZC in the handoff chain, if any.
if (i + 1 < mOverscrollHandoffChain.length()) {
next = mOverscrollHandoffChain[i + 1];
}
// Clear the handoff chain so we don't maintain references to APZCs
// unnecessarily.
mOverscrollHandoffChain.clear();
}
// Nothing to hand off fling to.
if (next == nullptr) {
return;
}
// The fling's velocity needs to be transformed from the screen coordinates
// of |aPrev| to the screen coordinates of |next|. To transform a velocity
// correctly, we need to convert it to a displacement. For now, we do this
// by anchoring it to a start point of (0, 0).
// TODO: For this to be correct in the presence of 3D transforms, we should
// use the end point of the touch that started the fling as the start point
// rather than (0, 0).
ScreenPoint startPoint; // (0, 0)
ScreenPoint endPoint = startPoint + aVelocity;
TransformDisplacement(this, aPrev, next, startPoint, endPoint);
ScreenPoint transformedVelocity = endPoint - startPoint;
// Tell |next| to start a fling with the transformed velocity.
next->TakeOverFling(transformedVelocity);
}
bool
APZCTreeManager::FlushRepaintsForOverscrollHandoffChain()
{
MonitorAutoLock lock(mTreeLock); // to access mOverscrollHandoffChain
if (mOverscrollHandoffChain.length() == 0) {
return false;
}
@ -799,6 +888,10 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtr<AsyncPanZoomControll
// handoff order can be different, so we build a chain of APZCs in the
// order in which scroll will be handed off to them.
// Grab tree lock to protect mOverscrollHandoffChain from concurrent
// access between the input and compositor threads.
MonitorAutoLock lock(mTreeLock);
mOverscrollHandoffChain.clear();
// Start with the child -> parent chain.
@ -822,6 +915,13 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtr<AsyncPanZoomControll
CompareByScrollPriority());
}
void
APZCTreeManager::ClearOverscrollHandoffChain()
{
MonitorAutoLock lock(mTreeLock);
mOverscrollHandoffChain.clear();
}
AsyncPanZoomController*
APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid)
{

View File

@ -41,6 +41,22 @@ class Layer;
class AsyncPanZoomController;
class CompositorParent;
/**
* ****************** NOTE ON LOCK ORDERING IN APZ **************************
*
* There are two kinds of locks used by APZ: APZCTreeManager::mTreeLock
* ("the tree lock") and AsyncPanZoomController::mMonitor ("APZC locks").
*
* To avoid deadlock, we impose a lock ordering between these locks, which is:
*
* tree lock -> APZC locks
*
* The interpretation of the lock ordering is that if lock A precedes lock B
* in the ordering sequence, then you must NOT wait on A while holding B.
*
* **************************************************************************
*/
/**
* This class manages the tree of AsyncPanZoomController instances. There is one
* instance of this class owned by each CompositorParent, and it contains as
@ -239,10 +255,22 @@ public:
* - TM.DispatchScroll() calls A.AttemptScroll() (since A is at index 2 in the chain)
* - A.AttemptScroll() scrolls A. If there is overscroll, it calls TM.DispatchScroll() with index = 3.
* - TM.DispatchScroll() discards the rest of the scroll as there are no more elements in the chain.
*
* Note: this should be used for panning only. For handing off overscroll for
* a fling, use HandOffFling().
*/
void DispatchScroll(AsyncPanZoomController* aAPZC, ScreenPoint aStartPoint, ScreenPoint aEndPoint,
uint32_t aOverscrollHandoffChainIndex);
/**
* This is a callback for AsyncPanZoomController to call when it wants to
* hand off overscroll from a fling.
* @param aApzc the APZC that is handing off the fling
* @param aVelocity the current velocity of the fling, in |aApzc|'s screen
* pixels per millisecond
*/
void HandOffFling(AsyncPanZoomController* aApzc, ScreenPoint aVelocity);
bool FlushRepaintsForOverscrollHandoffChain();
protected:
@ -279,6 +307,7 @@ private:
nsEventStatus ProcessEvent(WidgetInputEvent& inputEvent, ScrollableLayerGuid* aOutTargetGuid);
void UpdateZoomConstraintsRecursively(AsyncPanZoomController* aApzc,
const ZoomConstraints& aConstraints);
void ClearOverscrollHandoffChain();
/**
* Recursive helper function to build the APZC tree. The tree of APZC instances has
@ -303,7 +332,9 @@ private:
* This lock does not need to be held while manipulating a single APZC instance in
* isolation (that is, if its tree pointers are not being accessed or mutated). The
* lock also needs to be held when accessing the mRootApzc instance variable, as that
* is considered part of the APZC tree management state. */
* is considered part of the APZC tree management state.
* Finally, the lock needs to be held when accessing mOverscrollHandoffChain.
* IMPORTANT: See the note about lock ordering at the top of this file. */
mozilla::Monitor mTreeLock;
nsRefPtr<AsyncPanZoomController> mRootApzc;
/* This tracks the APZC that should receive all inputs for the current input event block.

View File

@ -31,6 +31,7 @@
#include "nsRect.h" // for nsIntRect
#include "nsRegion.h" // for nsIntRegion
#include "nsTArray.h" // for nsAutoTArray
#include "TextRenderer.h" // for TextRenderer
#include <vector>
namespace mozilla {
@ -120,6 +121,32 @@ static gfx::Point GetScrollData(Layer* aLayer) {
return origin;
}
static void DrawLayerInfo(const nsIntRect& aClipRect,
LayerManagerComposite* aManager,
Layer* aLayer)
{
if (aLayer->GetType() == Layer::LayerType::TYPE_CONTAINER) {
// XXX - should figure out a way to render this, but for now this
// is hard to do, since it will often get superimposed over the first
// child of the layer, which is bad.
return;
}
nsAutoCString layerInfo;
aLayer->PrintInfo(layerInfo, "");
nsIntRegion visibleRegion = aLayer->GetVisibleRegion();
uint32_t maxWidth = std::min<uint32_t>(visibleRegion.GetBounds().width, 500);
nsIntPoint topLeft = visibleRegion.GetBounds().TopLeft();
aManager->GetTextRenderer()->RenderText(layerInfo.get(), gfx::IntPoint(topLeft.x, topLeft.y),
aLayer->GetEffectiveTransform(), 16,
maxWidth);
}
static LayerVelocityUserData* GetVelocityData(Layer* aLayer) {
static char sLayerVelocityUserDataKey;
void* key = reinterpret_cast<void*>(&sLayerVelocityUserDataKey);
@ -361,6 +388,10 @@ ContainerRender(ContainerT* aContainer,
if (gfxPrefs::LayersScrollGraph()) {
DrawVelGraph(clipRect, aManager, layerToRender->GetLayer());
}
if (gfxPrefs::DrawLayerInfo()) {
DrawLayerInfo(clipRect, aManager, layerToRender->GetLayer());
}
// invariant: our GL context should be current here, I don't think we can
// assert it though
}

File diff suppressed because one or more lines are too long

View File

@ -51,6 +51,7 @@
#include <android/log.h>
#endif
#include "GeckoProfiler.h"
#include "TextRenderer.h" // for TextRenderer
class gfxASurface;
class gfxContext;
@ -104,6 +105,7 @@ LayerManagerComposite::LayerManagerComposite(Compositor* aCompositor)
, mIsCompositorReady(false)
, mDebugOverlayWantsNextFrame(false)
{
mTextRenderer = new TextRenderer(aCompositor);
MOZ_ASSERT(aCompositor);
}

View File

@ -61,6 +61,7 @@ class RefLayerComposite;
class SurfaceDescriptor;
class ThebesLayerComposite;
class TiledLayerComposer;
class TextRenderer;
struct FPSState;
class LayerManagerComposite : public LayerManager
@ -227,6 +228,8 @@ public:
void NotifyShadowTreeTransaction();
TextRenderer* GetTextRenderer() { return mTextRenderer; }
private:
/** Region we're clipping our current drawing to. */
nsIntRegion mClippingRegion;
@ -273,6 +276,8 @@ private:
bool mInTransaction;
bool mIsCompositorReady;
bool mDebugOverlayWantsNextFrame;
RefPtr<TextRenderer> mTextRenderer;
};
/**

View File

@ -0,0 +1,163 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
#include "TextRenderer.h"
#include "FontData.h"
#include "png.h"
#include "mozilla/Base64.h"
#include "mozilla/layers/Compositor.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/Effects.h"
namespace mozilla {
namespace layers {
using namespace gfx;
using namespace std;
const Float sBackgroundOpacity = 0.6f;
const SurfaceFormat sTextureFormat = SurfaceFormat::B8G8R8A8;
static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr)
{
png_read_update_info(png_ptr, info_ptr);
}
static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass)
{
MOZ_ASSERT(sTextureFormat == SurfaceFormat::B8G8R8A8);
DataSourceSurface::MappedSurface map = static_cast<TextRenderer*>(png_get_progressive_ptr(png_ptr))->GetSurfaceMap();
uint32_t* dst = (uint32_t*)(map.mData + map.mStride * row_num);
for (uint32_t x = 0; x < sTextureWidth; x++) {
// We blend to a transparent white background, this will make text readable
// even if it's on a dark background. Without hurting our ability to
// interact with the content behind the text.
Float alphaValue = Float(0xFF - new_row[x]) / 255.0f;
Float baseValue = sBackgroundOpacity * (1.0f - alphaValue);
Color pixelColor(baseValue, baseValue, baseValue, baseValue + alphaValue);
dst[x] = pixelColor.ToABGR();
}
}
TextRenderer::~TextRenderer()
{
if (mGlyphBitmaps) {
mGlyphBitmaps->Unmap();
}
}
void
TextRenderer::RenderText(const string& aText, const IntPoint& aOrigin,
const Matrix4x4& aTransform, uint32_t aTextSize,
uint32_t aTargetPixelWidth)
{
EnsureInitialized();
// For now we only have a bitmap font with a 16px cell size, so we just
// scale it up if the user wants larger text.
Float scaleFactor = Float(aTextSize) / Float(sCellHeight);
aTargetPixelWidth /= scaleFactor;
uint32_t numLines = 1;
uint32_t maxWidth = 0;
uint32_t lineWidth = 0;
// Calculate the size of the surface needed to draw all the glyphs.
for (uint32_t i = 0; i < aText.length(); i++) {
// Insert a line break if we go past the TargetPixelWidth.
// XXX - this has the downside of overrunning the intended width, causing
// things at the edge of a window to be cut off.
if (aText[i] == '\n' || (aText[i] == ' ' && lineWidth > aTargetPixelWidth)) {
numLines++;
lineWidth = 0;
continue;
}
lineWidth += sGlyphWidths[uint32_t(aText[i])];
maxWidth = std::max(lineWidth, maxWidth);
}
// Create a surface to draw our glyphs to.
RefPtr<DataSourceSurface> textSurf =
Factory::CreateDataSourceSurface(IntSize(maxWidth, numLines * sCellHeight), sTextureFormat);
DataSourceSurface::MappedSurface map;
textSurf->Map(DataSourceSurface::MapType::READ_WRITE, &map);
// Initialize the surface to transparent white.
memset(map.mData, uint8_t(sBackgroundOpacity * 255.0f),
numLines * sCellHeight * map.mStride);
uint32_t currentXPos = 0;
uint32_t currentYPos = 0;
// Copy our glyphs onto the surface.
for (uint32_t i = 0; i < aText.length(); i++) {
if (aText[i] == '\n' || (aText[i] == ' ' && currentXPos > aTargetPixelWidth)) {
currentYPos += sCellHeight;
currentXPos = 0;
continue;
}
uint32_t glyphXOffset = aText[i] % (sTextureWidth / sCellWidth) * sCellWidth * BytesPerPixel(sTextureFormat);
uint32_t truncatedLine = aText[i] / (sTextureWidth / sCellWidth);
uint32_t glyphYOffset = truncatedLine * sCellHeight * mMap.mStride;
for (int y = 0; y < 16; y++) {
memcpy(map.mData + (y + currentYPos) * map.mStride + currentXPos * BytesPerPixel(sTextureFormat),
mMap.mData + glyphYOffset + y * mMap.mStride + glyphXOffset,
sGlyphWidths[uint32_t(aText[i])] * BytesPerPixel(sTextureFormat));
}
currentXPos += sGlyphWidths[uint32_t(aText[i])];
}
textSurf->Unmap();
RefPtr<DataTextureSource> src = mCompositor->CreateDataTextureSource();
if (!src->Update(textSurf)) {
// Upload failed.
return;
}
RefPtr<EffectRGB> effect = new EffectRGB(src, true, Filter::LINEAR);
EffectChain chain;
chain.mPrimaryEffect = effect;
Matrix4x4 transform = aTransform;
transform.Scale(scaleFactor, scaleFactor, 1.0f);
mCompositor->DrawQuad(Rect(aOrigin.x, aOrigin.y, maxWidth, numLines * 16),
Rect(-10000, -10000, 20000, 20000), chain, 1.0f, transform);
}
void
TextRenderer::EnsureInitialized()
{
if (mGlyphBitmaps) {
return;
}
mGlyphBitmaps = Factory::CreateDataSourceSurface(IntSize(sTextureWidth, sTextureHeight), sTextureFormat);
mGlyphBitmaps->Map(DataSourceSurface::MapType::READ_WRITE, &mMap);
png_structp png_ptr = NULL;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
png_set_progressive_read_fn(png_ptr, this, info_callback, row_callback, nullptr);
png_infop info_ptr = NULL;
info_ptr = png_create_info_struct(png_ptr);
png_process_data(png_ptr, info_ptr, (uint8_t*)sFontPNG, sizeof(sFontPNG));
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
}
}
}

View File

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
#ifndef GFX_TextRenderer_H
#define GFX_TextRenderer_H
#include "mozilla/gfx/2D.h"
#include <string>
namespace mozilla {
namespace layers {
class Compositor;
class TextRenderer : public RefCounted<TextRenderer>
{
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(TextRenderer)
TextRenderer(Compositor *aCompositor)
: mCompositor(aCompositor)
{
}
~TextRenderer();
void RenderText(const std::string& aText, const gfx::IntPoint& aOrigin,
const gfx::Matrix4x4& aTransform, uint32_t aTextSize,
uint32_t aTargetPixelWidth);
gfx::DataSourceSurface::MappedSurface& GetSurfaceMap() { return mMap; }
private:
void EnsureInitialized();
RefPtr<Compositor> mCompositor;
RefPtr<gfx::DataSourceSurface> mGlyphBitmaps;
gfx::DataSourceSurface::MappedSurface mMap;
};
}
}
#endif

View File

@ -26,6 +26,7 @@
#include "nsRect.h" // for nsIntRect
#include "nsSize.h" // for nsIntSize
#include "nsString.h" // for nsAutoCString
#include "TextRenderer.h"
#include "GeckoProfiler.h"
namespace mozilla {

View File

@ -322,7 +322,7 @@ TiledContentHost::RenderTile(const TileHost& aTile,
Rect quad(screenBounds.x, screenBounds.y, screenBounds.width, screenBounds.height);
quad = mat.TransformBounds(quad);
if (!quad.Intersects(aClipRect)) {
if (!quad.Intersects(mCompositor->ClipRectInLayersCoordinates(aClipRect))) {
return;
}

View File

@ -312,6 +312,13 @@ static bool IsCloseToVertical(float aAngle, float aThreshold)
return (fabs(aAngle - (M_PI / 2)) < aThreshold);
}
template <typename Units>
static bool IsZero(const gfx::PointTyped<Units>& aPoint)
{
return FuzzyEqualsMultiplicative(aPoint.x, 0.0f)
&& FuzzyEqualsMultiplicative(aPoint.y, 0.0f);
}
static inline void LogRendertraceRect(const ScrollableLayerGuid& aGuid, const char* aDesc, const char* aColor, const CSSRect& aRect)
{
#ifdef APZC_ENABLE_RENDERTRACE
@ -339,10 +346,9 @@ GetFrameTime() {
class FlingAnimation: public AsyncPanZoomAnimation {
public:
FlingAnimation(AxisX& aX, AxisY& aY)
FlingAnimation(AsyncPanZoomController& aApzc)
: AsyncPanZoomAnimation(TimeDuration::FromMilliseconds(gFlingRepaintInterval))
, mX(aX)
, mY(aY)
, mApzc(aApzc)
{}
/**
* Advances a fling by an interpolated amount based on the passed in |aDelta|.
@ -354,8 +360,7 @@ public:
const TimeDuration& aDelta);
private:
AxisX& mX;
AxisY& mY;
AsyncPanZoomController& mApzc;
};
class ZoomAnimation: public AsyncPanZoomAnimation {
@ -750,8 +755,9 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
case PANNING_LOCKED_Y:
{
// Make a local copy of the tree manager pointer and check if it's not
// null before calling HandleOverscroll(). This is necessary because
// Destroy(), which nulls out mTreeManager, could be called concurrently.
// null before calling FlushRepaintsForOverscrollHandoffChain().
// This is necessary because Destroy(), which nulls out mTreeManager,
// could be called concurrently.
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
if (!treeManagerLocal->FlushRepaintsForOverscrollHandoffChain()) {
@ -764,7 +770,7 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
mX.EndTouch();
mY.EndTouch();
SetState(FLING);
StartAnimation(new FlingAnimation(mX, mY));
StartAnimation(new FlingAnimation(*this));
return nsEventStatus_eConsumeNoDefault;
case PINCHING:
@ -1152,18 +1158,18 @@ void AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
CSSToScreenScale zoom = mFrameMetrics.mZoom;
// Inversely scale the offset by the resolution (when you're zoomed further in,
// a larger swipe should move you a shorter distance).
// the same swipe should move you a shorter distance).
CSSPoint cssDisplacement = displacement / zoom;
CSSPoint cssOverscroll;
gfx::Point scrollOffset(mX.AdjustDisplacement(cssDisplacement.x,
cssOverscroll.x),
mY.AdjustDisplacement(cssDisplacement.y,
cssOverscroll.y));
CSSPoint allowedDisplacement(mX.AdjustDisplacement(cssDisplacement.x,
cssOverscroll.x),
mY.AdjustDisplacement(cssDisplacement.y,
cssOverscroll.y));
overscroll = cssOverscroll * zoom;
if (fabs(scrollOffset.x) > EPSILON || fabs(scrollOffset.y) > EPSILON) {
ScrollBy(CSSPoint::FromUnknownPoint(scrollOffset));
if (!IsZero(allowedDisplacement)) {
ScrollBy(allowedDisplacement);
ScheduleComposite();
TimeDuration timePaintDelta = mPaintThrottler.TimeSinceLastRequest(GetFrameTime());
@ -1174,17 +1180,26 @@ void AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
}
}
if (fabs(overscroll.x) > EPSILON || fabs(overscroll.y) > EPSILON) {
if (!IsZero(overscroll)) {
// "+ overscroll" rather than "- overscroll" because "overscroll" is what's
// left of "displacement", and "displacement" is "start - end".
CallDispatchScroll(aEndPoint + overscroll, aEndPoint, aOverscrollHandoffChainIndex + 1);
}
}
void AsyncPanZoomController::TakeOverFling(ScreenPoint aVelocity) {
// We may have a pre-existing velocity for whatever reason (for example,
// a previously handed off fling). We don't want to clobber that.
mX.SetVelocity(mX.GetVelocity() + aVelocity.x);
mY.SetVelocity(mY.GetVelocity() + aVelocity.y);
SetState(FLING);
StartAnimation(new FlingAnimation(*this));
}
void AsyncPanZoomController::CallDispatchScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint,
uint32_t aOverscrollHandoffChainIndex) {
// Make a local copy of the tree manager pointer and check if it's not
// null before calling HandleOverscroll(). This is necessary because
// null before calling DispatchScroll(). This is necessary because
// Destroy(), which nulls out mTreeManager, could be called concurrently.
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
@ -1240,24 +1255,76 @@ ScreenIntPoint& AsyncPanZoomController::GetFirstTouchScreenPoint(const MultiTouc
bool FlingAnimation::Sample(FrameMetrics& aFrameMetrics,
const TimeDuration& aDelta) {
bool shouldContinueFlingX = mX.FlingApplyFrictionOrCancel(aDelta),
shouldContinueFlingY = mY.FlingApplyFrictionOrCancel(aDelta);
// If the fling is handed off to our APZC from a child, on the first call to
// Sample() aDelta might be negative because it's computed as the sample time
// from SampleContentTransformForFrame() minus our APZC's mLastSampleTime
// which is the time the child handed off the fling from its call to
// SampleContentTransformForFrame() with the same sample time. If we allow
// the negative aDelta to be processed, it will yield a displacement in the
// direction opposite to the fling, which can cause us to overscroll and
// hand off the fling to _our_ parent, which effectively kills the fling.
if (aDelta.ToMilliseconds() <= 0) {
return true;
}
bool shouldContinueFlingX = mApzc.mX.FlingApplyFrictionOrCancel(aDelta),
shouldContinueFlingY = mApzc.mY.FlingApplyFrictionOrCancel(aDelta);
// If we shouldn't continue the fling, let's just stop and repaint.
if (!shouldContinueFlingX && !shouldContinueFlingY) {
return false;
}
CSSPoint overscroll; // overscroll is ignored for flings
ScreenPoint offset(aDelta.ToMilliseconds() * mX.GetVelocity(),
aDelta.ToMilliseconds() * mY.GetVelocity());
// AdjustDisplacement() zeroes out the Axis velocity if we're in overscroll.
// Since we need to hand off the velocity to the tree manager in such a case,
// we save it here. Would be ScreenVector instead of ScreenPoint if we had
// vector classes.
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
ScreenPoint offset = velocity * aDelta.ToMilliseconds();
// Inversely scale the offset by the resolution (when you're zoomed further in,
// a larger swipe should move you a shorter distance).
// the same swipe should move you a shorter distance).
CSSPoint cssOffset = offset / aFrameMetrics.mZoom;
aFrameMetrics.mScrollOffset += CSSPoint::FromUnknownPoint(gfx::Point(
mX.AdjustDisplacement(cssOffset.x, overscroll.x),
mY.AdjustDisplacement(cssOffset.y, overscroll.y)
));
CSSPoint overscroll;
aFrameMetrics.mScrollOffset += CSSPoint(
mApzc.mX.AdjustDisplacement(cssOffset.x, overscroll.x),
mApzc.mY.AdjustDisplacement(cssOffset.y, overscroll.y)
);
// If the fling has caused us to reach the end of our scroll range, hand
// off the fling to the next APZC in the overscroll handoff chain.
if (!IsZero(overscroll)) {
// We may have reached the end of the scroll range along one axis but
// not the other. In such a case we only want to hand off the relevant
// component of the fling.
if (FuzzyEqualsMultiplicative(overscroll.x, 0.0f)) {
velocity.x = 0;
} else if (FuzzyEqualsMultiplicative(overscroll.y, 0.0f)) {
velocity.y = 0;
}
// To hand off the fling, we call APZCTreeManager::HandleFlingOverscroll()
// which starts a new fling in the next APZC in the handoff chain with
// the same velocity. For simplicity, the actual overscroll of the current
// sample is discarded rather than being handed off. The compositor should
// sample animations sufficiently frequently that this is not noticeable.
// Make a local copy of the tree manager pointer and check if it's not
// null before calling HandleFlingOverscroll(). This is necessary because
// Destroy(), which nulls out mTreeManager, could be called concurrently.
APZCTreeManager* treeManagerLocal = mApzc.mTreeManager;
if (treeManagerLocal) {
// APZC is holding mMonitor, so directly calling HandleFlingOverscroll()
// (which acquires the tree lock) would violate the lock ordering. Instead
// we schedule HandleFlingOverscroll() to be called after mMonitor is
// released.
mDeferredTasks.append(NewRunnableMethod(treeManagerLocal,
&APZCTreeManager::HandOffFling,
&mApzc,
velocity));
}
}
return true;
}
@ -1535,6 +1602,12 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
mCurrentAsyncScrollOffset = mFrameMetrics.mScrollOffset;
}
// Execute tasks queued up by mAnimation's Sample() (called by
// UpdateAnimation()) for execution after mMonitor has been released.
if (mAnimation) {
mAnimation->ExecuteDeferredTasks();
}
// Cancel the mAsyncScrollTimeoutTask because we will fire a
// mozbrowserasyncscroll event or renew the mAsyncScrollTimeoutTask again.
if (mAsyncScrollTimeoutTask) {

View File

@ -40,6 +40,7 @@ class PCompositorParent;
class ViewTransform;
class APZCTreeManager;
class AsyncPanZoomAnimation;
class FlingAnimation;
/**
* Controller for all panning and zooming logic. Any time a user input is
@ -301,6 +302,12 @@ public:
void AttemptScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint,
uint32_t aOverscrollHandoffChainIndex = 0);
/**
* Take over a fling with the given velocity from another APZC. Used for
* during overscroll handoff for a fling.
*/
void TakeOverFling(ScreenPoint aVelocity);
/**
* Returns allowed touch behavior for the given point on the scrollable layer.
* Internally performs a kind of hit testing based on the regions constructed
@ -650,6 +657,7 @@ protected:
// Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
// monitor should be held. When setting |mState|, either the SetState()
// function can be used, or the monitor can be held and then |mState| updated.
// IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
ReentrantMonitor mMonitor;
// Specifies whether we should use touch-action css property. Initialized from
@ -747,6 +755,7 @@ private:
RefPtr<AsyncPanZoomAnimation> mAnimation;
friend class Axis;
friend class FlingAnimation;
/* The functions and members in this section are used to build a tree
* structure out of APZC instances. This tree can only be walked or
@ -864,12 +873,31 @@ public:
virtual bool Sample(FrameMetrics& aFrameMetrics,
const TimeDuration& aDelta) = 0;
/**
* Execute the tasks in |mDeferredTasks| in order. See |mDeferredTasks|
* for more information.
*/
void ExecuteDeferredTasks() {
for (uint32_t i = 0; i < mDeferredTasks.length(); ++i) {
mDeferredTasks[i]->Run();
}
mDeferredTasks.clear();
}
/**
* Specifies how frequently (at most) we want to do repaints during the
* animation sequence. TimeDuration::Forever() will cause it to only repaint
* at the end of the animation.
*/
TimeDuration mRepaintInterval;
protected:
/**
* Tasks scheduled for execution after the APZC's mMonitor is released.
* Derived classes can add tasks here in Sample(), and the APZC can call
* ExecuteDeferredTasks() to execute them.
*/
Vector<Task*> mDeferredTasks;
};
}

View File

@ -254,6 +254,10 @@ float Axis::GetVelocity() {
return mAxisLocked ? 0 : mVelocity;
}
void Axis::SetVelocity(float aVelocity) {
mVelocity = aVelocity;
}
float Axis::GetCompositionEnd() {
return GetOrigin() + GetCompositionLength();
}

View File

@ -128,6 +128,16 @@ public:
*/
float GetVelocity();
/**
* Sets the raw velocity of this axis at this moment.
* Intended to be called only when the axis "takes over" a velocity from
* another APZC, in which case there are no touch points available to call
* UpdateWithTouchAtDevicePoint. In other circumstances,
* UpdateWithTouchAtDevicePoint should be used and the velocity calculated
* there.
*/
void SetVelocity(float aVelocity);
/**
* Gets the overscroll state of the axis given an additional displacement.
* That is to say, if the given displacement is applied, this will tell you

View File

@ -211,6 +211,11 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
return true;
}
if (mLayerManager && mLayerManager->GetCompositor() &&
!targetConfig.naturalBounds().IsEmpty()) {
mLayerManager->GetCompositor()->SetScreenRotation(targetConfig.rotation());
}
// Clear fence handles used in previsou transaction.
ClearPrevFenceHandles();

View File

@ -251,6 +251,7 @@ UNIFIED_SOURCES += [
'composite/ImageHost.cpp',
'composite/ImageLayerComposite.cpp',
'composite/LayerManagerComposite.cpp',
'composite/TextRenderer.cpp',
'composite/TextureHost.cpp',
'composite/ThebesLayerComposite.cpp',
'composite/TiledContentHost.cpp',

View File

@ -154,6 +154,7 @@ private:
DECL_GFX_PREF(Live, "layers.draw-bigimage-borders", DrawBigImageBorders, bool, false);
DECL_GFX_PREF(Live, "layers.draw-borders", DrawLayerBorders, bool, false);
DECL_GFX_PREF(Live, "layers.draw-tile-borders", DrawTileBorders, bool, false);
DECL_GFX_PREF(Live, "layers.draw-layer-info", DrawLayerInfo, bool, false);
DECL_GFX_PREF(Once, "layers.dump", LayersDump, bool, false);
DECL_GFX_PREF(Once, "layers.enable-tiles", LayersTilesEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.simple-tiles", LayersUseSimpleTiles, bool, false);

View File

@ -210,6 +210,14 @@ RedirectCall(void *fun, ABIFunctionType type)
return fun;
}
#ifdef DEBUG
static void
AssumeUnreachable()
{
MOZ_CRASH("Reached unreachable code in asm.js");
}
#endif
static void *
AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
{
@ -274,6 +282,10 @@ AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
return RedirectCall(FuncCast(ecmaPow), Args_Double_DoubleDouble);
case AsmJSImm_ATan2D:
return RedirectCall(FuncCast(ecmaAtan2), Args_Double_DoubleDouble);
#ifdef DEBUG
case AsmJSImm_AssumeUnreachable:
return RedirectCall(FuncCast(AssumeUnreachable), Args_General0);
#endif
case AsmJSImm_Invalid:
break;
}

View File

@ -1279,20 +1279,24 @@ void
MacroAssembler::assumeUnreachable(const char *output)
{
#ifdef DEBUG
// AsmJS forbids use of ImmPtr.
if (!IsCompilingAsmJS()) {
RegisterSet regs = RegisterSet::Volatile();
PushRegsInMask(regs);
Register temp = regs.takeGeneral();
RegisterSet regs = RegisterSet::Volatile();
PushRegsInMask(regs);
Register temp = regs.takeGeneral();
// With ASLR, we can't rely on 'output' to point to the
// same char array after serialization/deserialization.
// It is not possible until we modify AsmJsImmPtr and
// the underlying "patching" mechanism.
if (IsCompilingAsmJS()) {
setupUnalignedABICall(0, temp);
callWithABINoProfiling(AsmJSImm_AssumeUnreachable);
} else {
setupUnalignedABICall(1, temp);
movePtr(ImmPtr(output), temp);
passABIArg(temp);
callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_));
PopRegsInMask(RegisterSet::Volatile());
}
PopRegsInMask(RegisterSet::Volatile());
#endif
breakpoint();

View File

@ -704,6 +704,9 @@ enum AsmJSImmKind
AsmJSImm_LogD,
AsmJSImm_PowD,
AsmJSImm_ATan2D,
#ifdef DEBUG
AsmJSImm_AssumeUnreachable,
#endif
AsmJSImm_Invalid
};

View File

@ -1228,8 +1228,10 @@ nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame,
}
void
nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine,
int32_t aNumFramesOnLine)
nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine,
int32_t aNumFramesOnLine,
WritingMode aLineWM,
nscoord& aLineWidth)
{
// If this line consists of a line frame, reorder the line frame's children.
if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) {
@ -1242,7 +1244,7 @@ nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine,
}
BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine);
RepositionInlineFrames(&bld, aFirstFrameOnLine);
RepositionInlineFrames(&bld, aFirstFrameOnLine, aLineWM, aLineWidth);
}
nsIFrame*
@ -1282,22 +1284,20 @@ nsBidiPresUtils::GetFrameBaseLevel(nsIFrame* aFrame)
}
void
nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
nsContinuationStates* aContinuationStates,
bool& aIsLeftMost /* out */,
bool& aIsRightMost /* out */)
nsBidiPresUtils::IsFirstOrLast(nsIFrame* aFrame,
nsContinuationStates* aContinuationStates,
bool& aIsFirst /* out */,
bool& aIsLast /* out */)
{
const nsStyleVisibility* vis = aFrame->StyleVisibility();
bool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection);
/*
* Since we lay out frames from left to right (in both LTR and RTL), visiting a
* frame with 'mFirstVisualFrame == nullptr', means it's the first appearance of
* one of its continuation chain frames on the line.
* To determine if it's the last visual frame of its continuation chain on the line
* or not, we count the number of frames of the chain on the line, and then reduce
* it when we lay out a frame of the chain. If this value becomes 1 it means
* that it's the last visual frame of its continuation chain on this line.
* Since we lay out frames in the line's direction, visiting a frame with
* 'mFirstVisualFrame == nullptr', means it's the first appearance of one
* of its continuation chain frames on the line.
* To determine if it's the last visual frame of its continuation chain on
* the line or not, we count the number of frames of the chain on the line,
* and then reduce it when we lay out a frame of the chain. If this value
* becomes 1 it means that it's the last visual frame of its continuation
* chain on this line.
*/
nsFrameContinuationState* frameState = aContinuationStates->GetEntry(aFrame);
@ -1334,20 +1334,18 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
}
frameState->mHasContOnNextLines = (frame != nullptr);
aIsLeftMost = isLTR ? !frameState->mHasContOnPrevLines
: !frameState->mHasContOnNextLines;
aIsFirst = !frameState->mHasContOnPrevLines;
firstFrameState = frameState;
} else {
// aFrame is not the first visual frame of its continuation chain
aIsLeftMost = false;
aIsFirst = false;
firstFrameState = aContinuationStates->GetEntry(frameState->mFirstVisualFrame);
}
aIsRightMost = (firstFrameState->mFrameCount == 1) &&
(isLTR ? !firstFrameState->mHasContOnNextLines
: !firstFrameState->mHasContOnPrevLines);
aIsLast = (firstFrameState->mFrameCount == 1 &&
!firstFrameState->mHasContOnNextLines);
if ((aIsLeftMost || aIsRightMost) &&
if ((aIsFirst || aIsLast) &&
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
// For ib splits, don't treat anything except the last part as
// endmost or anything except the first part as startmost.
@ -1355,19 +1353,11 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
nsIFrame* firstContinuation = aFrame->FirstContinuation();
if (firstContinuation->FrameIsNonLastInIBSplit()) {
// We are not endmost
if (isLTR) {
aIsRightMost = false;
} else {
aIsLeftMost = false;
}
aIsLast = false;
}
if (firstContinuation->FrameIsNonFirstInIBSplit()) {
// We are not startmost
if (isLTR) {
aIsLeftMost = false;
} else {
aIsRightMost = false;
}
aIsFirst = false;
}
}
@ -1376,29 +1366,39 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame,
}
void
nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
bool aIsOddLevel,
nscoord& aLeft,
nsContinuationStates* aContinuationStates)
nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
bool aIsEvenLevel,
nscoord& aStart,
nsContinuationStates* aContinuationStates,
WritingMode aLineWM,
nscoord& aLineWidth)
{
if (!aFrame)
return;
bool isLeftMost, isRightMost;
IsLeftOrRightMost(aFrame,
aContinuationStates,
isLeftMost /* out */,
isRightMost /* out */);
bool isFirst, isLast;
IsFirstOrLast(aFrame,
aContinuationStates,
isFirst /* out */,
isLast /* out */);
WritingMode frameWM = aFrame->GetWritingMode();
nsInlineFrame* testFrame = do_QueryFrame(aFrame);
//XXX temporary until GetSkipSides is logicalized
bool isLeftMost = false, isRightMost = false;
if (testFrame) {
aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_STATE_IS_SET);
isLeftMost = ((isFirst && frameWM.IsBidiLTR()) ||
(isLast && !frameWM.IsBidiLTR()));
if (isLeftMost)
aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LEFT_MOST);
else
aFrame->RemoveStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_LEFT_MOST);
isRightMost = ((isLast && frameWM.IsBidiLTR()) ||
(isFirst && !frameWM.IsBidiLTR()));
if (isRightMost)
aFrame->AddStateBits(NS_INLINE_FRAME_BIDI_VISUAL_IS_RIGHT_MOST);
else
@ -1407,26 +1407,30 @@ nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
// This method is called from nsBlockFrame::PlaceLine via the call to
// bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines
// have been reflowed, which is required for GetUsedMargin/Border/Padding
nsMargin margin = aFrame->GetUsedMargin();
if (isLeftMost)
aLeft += margin.left;
LogicalMargin margin(frameWM, aFrame->GetUsedMargin());
if (isFirst) {
aStart += margin.IStart(frameWM);
}
nscoord start = aLeft;
nscoord start = aStart;
nscoord frameWidth = aFrame->GetSize().width;
if (!IsBidiLeaf(aFrame))
{
nscoord x = 0;
nsMargin borderPadding = aFrame->GetUsedBorderAndPadding();
if (isLeftMost) {
x += borderPadding.left;
nscoord iCoord = 0;
LogicalMargin borderPadding(frameWM, aFrame->GetUsedBorderAndPadding());
if (isFirst) {
iCoord += borderPadding.IStart(frameWM);
}
// If aIsOddLevel is true, so we need to traverse the child list
// in reverse order, to make it O(n) we store the list locally and
// iterate the list reversely
// If the resolved direction of the container is different from the
// direction of the frame, we need to traverse the child list in reverse
// order, to make it O(n) we store the list locally and iterate the list
// in reverse
bool reverseOrder = aIsEvenLevel != frameWM.IsBidiLTR();
nsTArray<nsIFrame*> childList;
nsIFrame *frame = aFrame->GetFirstPrincipalChild();
if (frame && aIsOddLevel) {
if (frame && reverseOrder) {
childList.AppendElement((nsIFrame*)nullptr);
while (frame) {
childList.AppendElement(frame);
@ -1439,27 +1443,33 @@ nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame,
int32_t index = 0;
while (frame) {
RepositionFrame(frame,
aIsOddLevel,
x,
aContinuationStates);
aIsEvenLevel,
iCoord,
aContinuationStates,
frameWM,
frameWidth);
index++;
frame = aIsOddLevel ?
frame = reverseOrder ?
childList[childList.Length() - index - 1] :
frame->GetNextSibling();
}
if (isRightMost) {
x += borderPadding.right;
if (isLast) {
iCoord += borderPadding.IEnd(frameWM);
}
aLeft += x;
aStart += iCoord;
} else {
aLeft += aFrame->GetSize().width;
aStart += frameWidth;
}
nsRect rect = aFrame->GetRect();
aFrame->SetRect(nsRect(start, rect.y, aLeft - start, rect.height));
if (isRightMost)
aLeft += margin.right;
LogicalRect logicalRect(aLineWM, aFrame->GetRect(), aLineWidth);
logicalRect.IStart(aLineWM) = start;
logicalRect.ISize(aLineWM) = aStart - start;
aFrame->SetRect(aLineWM, logicalRect, aLineWidth);
if (isLast) {
aStart += margin.IEnd(frameWM);
}
}
void
@ -1484,21 +1494,23 @@ nsBidiPresUtils::InitContinuationStates(nsIFrame* aFrame,
void
nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld,
nsIFrame* aFirstChild)
nsIFrame* aFirstChild,
WritingMode aLineWM,
nscoord& aLineWidth)
{
const nsStyleVisibility* vis = aFirstChild->StyleVisibility();
bool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection);
nscoord leftSpace = 0;
nscoord startSpace = 0;
// This method is called from nsBlockFrame::PlaceLine via the call to
// bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines
// have been reflowed, which is required for GetUsedMargin/Border/Padding
nsMargin margin = aFirstChild->GetUsedMargin();
WritingMode frameWM = aFirstChild->GetWritingMode();
LogicalMargin margin(frameWM, aFirstChild->GetUsedMargin());
if (!aFirstChild->GetPrevContinuation() &&
!aFirstChild->FrameIsNonFirstInIBSplit())
leftSpace = isLTR ? margin.left : margin.right;
startSpace = margin.IStart(frameWM);
nscoord left = aFirstChild->GetPosition().x - leftSpace;
nscoord start = LogicalRect(aLineWM, aFirstChild->GetRect(),
aLineWidth).IStart(aLineWM) - startSpace;
nsIFrame* frame;
int32_t count = aBld->mVisualFrames.Length();
int32_t index;
@ -1511,13 +1523,25 @@ nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld,
}
// Reposition frames in visual order
for (index = 0; index < count; index++) {
int32_t step, limit;
if (aLineWM.IsBidiLTR()) {
index = 0;
step = 1;
limit = count;
} else {
index = count - 1;
step = -1;
limit = -1;
}
for (; index != limit; index += step) {
frame = aBld->VisualFrameAt(index);
RepositionFrame(frame,
(aBld->mLevels[aBld->mIndexMap[index]] & 1),
left,
&continuationStates);
} // for
!(aBld->mLevels[aBld->mIndexMap[index]] & 1),
start,
&continuationStates,
aLineWM,
aLineWidth);
}
}
bool

View File

@ -27,6 +27,7 @@ class nsRenderingContext;
class nsBlockInFlowLineIterator;
class nsStyleContext;
template<class T> class nsTHashtable;
namespace mozilla { class WritingMode; }
/**
* A structure representing some continuation state for each frame on the line,
@ -159,7 +160,9 @@ public:
* @lina 05/02/2000
*/
static void ReorderFrames(nsIFrame* aFirstFrameOnLine,
int32_t aNumFramesOnLine);
int32_t aNumFramesOnLine,
mozilla::WritingMode aLineWM,
nscoord& aLineWidth);
/**
* Format Unicode text, taking into account bidi capabilities
@ -377,24 +380,27 @@ private:
nsBlockInFlowLineIterator* aLineIter,
nsIFrame* aCurrentFrame,
BidiParagraphData* aBpd);
/*
* Position aFrame and it's descendants to their visual places. Also if aFrame
* is not leaf, resize it to embrace it's children.
* Position aFrame and its descendants to their visual places. Also if aFrame
* is not leaf, resize it to embrace its children.
*
* @param aFrame The frame which itself and its children are going
* to be repositioned
* @param aIsOddLevel TRUE means the embedding level of this frame is odd
* @param[in,out] aLeft IN value is the starting position of aFrame(without
* considering its left margin)
* OUT value will be the ending position of aFrame(after
* adding its right margin)
* @param aFrame The frame which itself and its children are
* going to be repositioned
* @param aIsEvenLevel TRUE means the embedding level of this frame
* is even (LTR)
* @param[in,out] aStart IN value is the starting position of aFrame
* (without considering its inline-start margin)
* OUT value will be the ending position of aFrame
* (after adding its inline-end margin)
* @param aContinuationStates A map from nsIFrame* to nsFrameContinuationState
*/
static void RepositionFrame(nsIFrame* aFrame,
bool aIsOddLevel,
nscoord& aLeft,
nsContinuationStates* aContinuationStates);
bool aIsEvenLevel,
nscoord& aStart,
nsContinuationStates* aContinuationStates,
mozilla::WritingMode aLineWM,
nscoord& aLineWidth);
/*
* Initialize the continuation state(nsFrameContinuationState) to
@ -422,10 +428,10 @@ private:
* @param[out] aIsLeftMost TRUE means aFrame is leftmost frame or continuation
* @param[out] aIsRightMost TRUE means aFrame is rightmost frame or continuation
*/
static void IsLeftOrRightMost(nsIFrame* aFrame,
nsContinuationStates* aContinuationStates,
bool& aIsLeftMost /* out */,
bool& aIsRightMost /* out */);
static void IsFirstOrLast(nsIFrame* aFrame,
nsContinuationStates* aContinuationStates,
bool& aIsFirst /* out */,
bool& aIsLast /* out */);
/**
* Adjust frame positions following their visual order
@ -435,7 +441,9 @@ private:
* @lina 04/11/2000
*/
static void RepositionInlineFrames(BidiLineData* aBld,
nsIFrame* aFirstChild);
nsIFrame* aFirstChild,
mozilla::WritingMode aLineWM,
nscoord& aLineWidth);
/**
* Helper method for Resolve()

View File

@ -833,6 +833,12 @@ public:
*this : LogicalMargin(aToMode, GetPhysicalMargin(aFromMode));
}
bool IsEmpty() const
{
return (mMargin.left == 0 && mMargin.top == 0 &&
mMargin.right == 0 && mMargin.bottom == 0);
}
private:
friend class LogicalRect;
@ -1123,6 +1129,17 @@ public:
return aWritingMode.IsVertical() ? mRect.XMost() : mRect.YMost();
}
bool IsEmpty() const
{
return (mRect.x == 0 && mRect.y == 0 &&
mRect.width == 0 && mRect.height == 0);
}
bool IsZeroSize() const
{
return (mRect.width == 0 && mRect.height == 0);
}
/* XXX are these correct?
nscoord ILeft(WritingMode aWritingMode) const
{

View File

@ -1450,7 +1450,7 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
*aBottomEdgeOfChildren = bottomEdgeOfChildren;
#ifdef DEBUG_blocks
if (CRAZY_WIDTH(aMetrics.Width()) || CRAZY_HEIGHT(aMetrics.Height())) {
if (CRAZY_SIZE(aMetrics.Width()) || CRAZY_SIZE(aMetrics.Height())) {
ListTag(stdout);
printf(": WARNING: desired:%d,%d\n", aMetrics.Width(), aMetrics.Height());
}
@ -3448,35 +3448,32 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
this, aFloatAvailableSpace.mHasFloats);
#endif
nscoord x = aFloatAvailableSpace.mRect.x;
nscoord availWidth = aFloatAvailableSpace.mRect.width;
nscoord availHeight;
WritingMode wm = GetWritingMode(aLine->mFirstChild);
nscoord lineWidth = aFloatAvailableSpace.mRect.width +
aState.BorderPadding().LeftRight();
LogicalRect lineRect(wm, aFloatAvailableSpace.mRect, lineWidth);
nscoord iStart = lineRect.IStart(wm);
nscoord availISize = lineRect.ISize(wm);
nscoord availBSize;
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
availHeight = NS_UNCONSTRAINEDSIZE;
availBSize = NS_UNCONSTRAINEDSIZE;
}
else {
/* XXX get the height right! */
availHeight = aFloatAvailableSpace.mRect.height;
availBSize = lineRect.BSize(wm);
}
// Make sure to enable resize optimization before we call BeginLineReflow
// because it might get disabled there
aLine->EnableResizeReflowOptimization();
// For unicode-bidi: plaintext, we need to get the direction of the line from
// the resolved paragraph level of the first frame on the line, not the block
// frame, because the block frame could be split by hard line breaks into
// multiple paragraphs with different base direction
uint8_t direction =
(StyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_PLAINTEXT) ?
nsBidiPresUtils::GetFrameBaseLevel(aLine->mFirstChild) & 1 :
StyleVisibility()->mDirection;
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
aLineLayout.BeginLineReflow(iStart, aState.mY,
availISize, availBSize,
aFloatAvailableSpace.mHasFloats,
false, /*XXX isTopOfPage*/
direction);
wm, lineWidth);
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, false);
@ -4052,7 +4049,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
bool addedBullet = false;
if (HasOutsideBullet() &&
((aLine == mLines.front() &&
(!aLineLayout.IsZeroHeight() || (aLine == mLines.back()))) ||
(!aLineLayout.IsZeroBSize() || (aLine == mLines.back()))) ||
(mLines.front() != mLines.back() &&
0 == mLines.front()->mBounds.height &&
aLine == mLines.begin().next()))) {
@ -4064,7 +4061,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
aLineLayout.AddBulletFrame(bullet, metrics);
addedBullet = true;
}
aLineLayout.VerticalAlignLine();
aLineLayout.BlockDirAlignLine();
// We want to compare to the available space that we would have had in
// the line's height *before* we placed any floats in the line itself.
@ -4092,9 +4089,9 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
#ifdef DEBUG
{
static nscoord lastHeight = 0;
if (CRAZY_HEIGHT(aLine->mBounds.y)) {
if (CRAZY_SIZE(aLine->mBounds.y)) {
lastHeight = aLine->mBounds.y;
if (abs(aLine->mBounds.y - lastHeight) > CRAZY_H/10) {
if (abs(aLine->mBounds.y - lastHeight) > CRAZY_COORD/10) {
nsFrame::ListTag(stdout);
printf(": line=%p y=%d line.bounds.height=%d\n",
static_cast<void*>(aLine.get()),
@ -4125,20 +4122,9 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
NS_STYLE_TEXT_ALIGN_JUSTIFY == styleText->mTextAlign) &&
(aLineLayout.GetLineEndsInBR() ||
IsLastLine(aState, aLine)));
aLineLayout.HorizontalAlignFrames(aLine->mBounds, isLastLine);
// XXX: not only bidi: right alignment can be broken after
// RelativePositionFrames!!!
// XXXldb Is something here considering relatively positioned frames at
// other than their original positions?
#ifdef IBMBIDI
// XXXldb Why don't we do this earlier?
if (aState.mPresContext->BidiEnabled()) {
if (!aState.mPresContext->IsVisualMode() ||
StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
nsBidiPresUtils::ReorderFrames(aLine->mFirstChild, aLine->GetChildCount());
} // not visual mode
} // bidi enabled
#endif // IBMBIDI
aLineLayout.InlineDirAlignFrames(aLine->mBounds, isLastLine,
aLine->GetChildCount());
// From here on, pfd->mBounds rectangles are incorrect because bidi
// might have moved frames around!

View File

@ -262,7 +262,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
#ifdef DEBUG
if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) {
if (CRAZY_WIDTH(mMetrics.Width()) || CRAZY_HEIGHT(mMetrics.Height())) {
if (CRAZY_SIZE(mMetrics.Width()) || CRAZY_SIZE(mMetrics.Height())) {
printf("nsBlockReflowContext: ");
nsFrame::ListTag(stdout, mFrame);
printf(" metrics=%d,%d!\n", mMetrics.Width(), mMetrics.Height());

View File

@ -34,11 +34,8 @@ class FramePropertyTable;
// dependency on nsDeviceContext.h. It doesn't matter if it's a
// little off.
#ifdef DEBUG
#define CRAZY_W (1000000*60)
#define CRAZY_H CRAZY_W
#define CRAZY_WIDTH(_x) (((_x) < -CRAZY_W) || ((_x) > CRAZY_W))
#define CRAZY_HEIGHT(_y) (((_y) < -CRAZY_H) || ((_y) > CRAZY_H))
#define CRAZY_COORD (1000000*60)
#define CRAZY_SIZE(_x) (((_x) < -CRAZY_COORD) || ((_x) > CRAZY_COORD))
#endif
/**

View File

@ -188,21 +188,10 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowState rs(aPresContext, aReflowState, kid, availSize);
nsLineLayout ll(aPresContext, nullptr, &aReflowState, nullptr);
// For unicode-bidi: plaintext, we need to get the direction of the line
// from the resolved paragraph level of the child, not the block frame,
// because the block frame could be split by hard line breaks into
// multiple paragraphs with different base direction
uint8_t direction;
nsIFrame* containerFrame = ll.LineContainerFrame();
if (containerFrame->StyleTextReset()->mUnicodeBidi &
NS_STYLE_UNICODE_BIDI_PLAINTEXT) {
FramePropertyTable *propTable = aPresContext->PropertyTable();
direction = NS_PTR_TO_INT32(propTable->Get(kid, BaseLevelProperty())) & 1;
} else {
direction = containerFrame->StyleVisibility()->mDirection;
}
ll.BeginLineReflow(bp.left, bp.top, availSize.width, NS_UNCONSTRAINEDSIZE,
false, true, direction);
false, true,
ll.LineContainerFrame()->GetWritingMode(kid),
aReflowState.AvailableWidth());
rs.mLineLayout = &ll;
ll.SetInFirstLetter(true);
ll.SetFirstLetterStyleOK(true);

View File

@ -975,6 +975,20 @@ nsIFrame::GetPaddingRect() const
return GetPaddingRectRelativeToSelf() + GetPosition();
}
WritingMode
nsIFrame::GetWritingMode(nsIFrame* aSubFrame) const
{
WritingMode writingMode = GetWritingMode();
if (!writingMode.IsVertical() &&
(StyleTextReset()->mUnicodeBidi & NS_STYLE_UNICODE_BIDI_PLAINTEXT)) {
nsBidiLevel frameLevel = nsBidiPresUtils::GetFrameBaseLevel(aSubFrame);
writingMode.SetDirectionFromBidiLevel(frameLevel);
}
return writingMode;
}
nsRect
nsIFrame::GetMarginRectRelativeToSelf() const
{

View File

@ -672,6 +672,15 @@ public:
return mozilla::WritingMode(StyleVisibility());
}
/**
* Get the writing mode of this frame, but if it is styled with
* unicode-bidi: plaintext, reset the direction to the resolved paragraph
* level of the given subframe (typically the first frame on the line),
* not this frame's writing mode, because the container frame could be split
* by hard line breaks into multiple paragraphs with different base direction.
*/
mozilla::WritingMode GetWritingMode(nsIFrame* aSubFrame) const;
/**
* Bounding rect of the frame. The values are in app units, and the origin is
* relative to the upper-left of the geometric parent. The size includes the

View File

@ -487,23 +487,21 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
nsLineLayout* lineLayout = aReflowState.mLineLayout;
bool inFirstLine = aReflowState.mLineLayout->GetInFirstLine();
RestyleManager* restyleManager = aPresContext->RestyleManager();
bool ltr = (NS_STYLE_DIRECTION_LTR == aReflowState.mStyleVisibility->mDirection);
nscoord leftEdge = 0;
WritingMode wm = aReflowState.GetWritingMode();
nscoord startEdge = 0;
// Don't offset by our start borderpadding if we have a prev continuation or
// if we're in a part of an {ib} split other than the first one.
if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
leftEdge = ltr ? aReflowState.ComputedPhysicalBorderPadding().left
: aReflowState.ComputedPhysicalBorderPadding().right;
startEdge = aReflowState.ComputedLogicalBorderPadding().IStart(wm);
}
nscoord availableWidth = aReflowState.AvailableWidth();
NS_ASSERTION(availableWidth != NS_UNCONSTRAINEDSIZE,
nscoord availableISize = aReflowState.AvailableISize();
NS_ASSERTION(availableISize != NS_UNCONSTRAINEDSIZE,
"should no longer use available widths");
// Subtract off left and right border+padding from availableWidth
availableWidth -= leftEdge;
availableWidth -= ltr ? aReflowState.ComputedPhysicalBorderPadding().right
: aReflowState.ComputedPhysicalBorderPadding().left;
lineLayout->BeginSpan(this, &aReflowState, leftEdge,
leftEdge + availableWidth, &mBaseline);
// Subtract off inline axis border+padding from availableISize
availableISize -= startEdge;
availableISize -= aReflowState.ComputedLogicalBorderPadding().IEnd(wm);
lineLayout->BeginSpan(this, &aReflowState, startEdge,
startEdge + availableISize, &mBaseline);
// First reflow our principal children.
nsIFrame* frame = mFrames.FirstChild();
@ -646,7 +644,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
// line-height calculations. However, continuations of an inline
// that are empty we force to empty so that things like collapsed
// whitespace in an inline element don't affect the line-height.
aMetrics.Width() = lineLayout->EndSpan(this);
aMetrics.ISize() = lineLayout->EndSpan(this);
// Compute final width.
@ -654,8 +652,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
// continuation or if we're in a part of an {ib} split other than the first
// one.
if (!GetPrevContinuation() && !FrameIsNonFirstInIBSplit()) {
aMetrics.Width() += ltr ? aReflowState.ComputedPhysicalBorderPadding().left
: aReflowState.ComputedPhysicalBorderPadding().right;
aMetrics.ISize() += aReflowState.ComputedLogicalBorderPadding().IStart(wm);
}
/*
@ -668,8 +665,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
if (NS_FRAME_IS_COMPLETE(aStatus) &&
!LastInFlow()->GetNextContinuation() &&
!FrameIsNonLastInIBSplit()) {
aMetrics.Width() += ltr ? aReflowState.ComputedPhysicalBorderPadding().right
: aReflowState.ComputedPhysicalBorderPadding().left;
aMetrics.Width() += aReflowState.ComputedLogicalBorderPadding().IEnd(wm);
}
nsRefPtr<nsFontMetrics> fm;

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include "nsBlockReflowState.h"
#include "plarena.h"
#include "gfxTypes.h"
#include "WritingModes.h"
class nsFloatManager;
struct nsStyleText;
@ -33,10 +34,10 @@ public:
const nsLineList::iterator* aLine);
~nsLineLayout();
void Init(nsBlockReflowState* aState, nscoord aMinLineHeight,
void Init(nsBlockReflowState* aState, nscoord aMinLineBSize,
int32_t aLineNumber) {
mBlockRS = aState;
mMinLineHeight = aMinLineHeight;
mMinLineBSize = aMinLineBSize;
mLineNumber = aLineNumber;
}
@ -44,11 +45,12 @@ public:
return mLineNumber;
}
void BeginLineReflow(nscoord aX, nscoord aY,
nscoord aWidth, nscoord aHeight,
void BeginLineReflow(nscoord aICoord, nscoord aBCoord,
nscoord aISize, nscoord aBSize,
bool aImpactedByFloats,
bool aIsTopOfPage,
uint8_t aDirection);
mozilla::WritingMode aWritingMode,
nscoord aContainerWidth);
void EndLineReflow();
@ -73,7 +75,7 @@ public:
void SplitLineTo(int32_t aNewCount);
bool IsZeroHeight();
bool IsZeroBSize();
// Reflows the frame and returns the reflow status. aPushedFrame is true
// if the frame is pushed to the next line because it doesn't fit
@ -88,11 +90,12 @@ public:
PushFrame(aFrame);
}
void VerticalAlignLine();
void BlockDirAlignLine();
bool TrimTrailingWhiteSpace();
void HorizontalAlignFrames(nsRect& aLineBounds, bool aIsLastLine);
void InlineDirAlignFrames(nsRect& aLineBounds, bool aIsLastLine,
int32_t aFrameCount);
/**
* Handle all the relative positioning in the line, compute the
@ -303,10 +306,10 @@ public:
* the right edge for RTL blocks and from the left edge for LTR blocks.
* In other words, the current frame's distance from the line container's
* start content edge is:
* <code>GetCurrentFrameXDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code>
* <code>GetCurrentFrameInlineDistanceFromBlock() - lineContainer->GetUsedBorderAndPadding().left</code>
* Note the use of <code>.left</code> for both LTR and RTL line containers.
*/
nscoord GetCurrentFrameXDistanceFromBlock();
nscoord GetCurrentFrameInlineDistanceFromBlock();
protected:
// This state is constant for a given block frame doing line layout
@ -326,14 +329,22 @@ protected:
// Per-frame data recorded by the line-layout reflow logic. This
// state is the state needed to post-process the line after reflow
// has completed (vertical alignment, horizontal alignment,
// has completed (block-direction alignment, inline-direction alignment,
// justification and relative positioning).
struct PerSpanData;
struct PerFrameData;
friend struct PerSpanData;
friend struct PerFrameData;
struct PerFrameData {
struct PerFrameData
{
PerFrameData(mozilla::WritingMode aWritingMode)
: mBounds(aWritingMode)
, mMargin(aWritingMode)
, mBorderPadding(aWritingMode)
, mOffsets(aWritingMode)
{}
// link to next/prev frame in same span
PerFrameData* mNext;
PerFrameData* mPrev;
@ -346,20 +357,23 @@ protected:
// From metrics
nscoord mAscent;
nsRect mBounds;
// note that mBounds is a logical rect in the *line*'s writing mode.
// When setting frame coordinates, we have to convert to the frame's
// writing mode
mozilla::LogicalRect mBounds;
nsOverflowAreas mOverflowAreas;
// From reflow-state
nsMargin mMargin;
nsMargin mBorderPadding;
nsMargin mOffsets;
mozilla::LogicalMargin mMargin;
mozilla::LogicalMargin mBorderPadding;
mozilla::LogicalMargin mOffsets;
// state for text justification
int32_t mJustificationNumSpaces;
int32_t mJustificationNumLetters;
// Other state we use
uint8_t mVerticalAlign;
uint8_t mBlockDirAlign;
// PerFrameData flags
#define PFD_RELATIVEPOS 0x00000001
@ -414,19 +428,18 @@ protected:
const nsHTMLReflowState* mReflowState;
bool mNoWrap;
uint8_t mDirection;
bool mChangedFrameDirection;
mozilla::WritingMode mWritingMode;
bool mZeroEffectiveSpanBox;
bool mContainsFloat;
bool mHasNonemptyContent;
nscoord mLeftEdge;
nscoord mX;
nscoord mRightEdge;
nscoord mIStart;
nscoord mICoord;
nscoord mIEnd;
nscoord mTopLeading, mBottomLeading;
nscoord mLogicalHeight;
nscoord mMinY, mMaxY;
nscoord mBStartLeading, mBEndLeading;
nscoord mLogicalBSize;
nscoord mMinBCoord, mMaxBCoord;
nscoord* mBaseline;
void AppendFrame(PerFrameData* pfd) {
@ -448,7 +461,7 @@ protected:
int32_t mLastOptionalBreakContentOffset;
int32_t mForceBreakContentOffset;
nscoord mMinLineHeight;
nscoord mMinLineBSize;
// The amount of text indent that we applied to this line, needed for
// max-element-size calculation.
@ -462,19 +475,21 @@ protected:
int32_t mTotalPlacedFrames;
nscoord mTopEdge;
nscoord mMaxTopBoxHeight;
nscoord mMaxBottomBoxHeight;
nscoord mBStartEdge;
nscoord mMaxStartBoxBSize;
nscoord mMaxEndBoxBSize;
nscoord mInflationMinFontSize;
// Final computed line-height value after VerticalAlignFrames for
// Final computed line-bSize value after BlockDirAlignFrames for
// the block has been called.
nscoord mFinalLineHeight;
nscoord mFinalLineBSize;
// Amount of trimmable whitespace width for the trailing text frame, if any
nscoord mTrimmableWidth;
nscoord mContainerWidth;
bool mFirstLetterStyleOK : 1;
bool mIsTopOfPage : 1;
bool mImpactedByFloats : 1;
@ -499,7 +514,7 @@ protected:
/**
* Allocate a PerFrameData from the mArena pool. The allocation is infallible.
*/
PerFrameData* NewPerFrameData();
PerFrameData* NewPerFrameData(nsIFrame* aFrame);
/**
* Allocate a PerSpanData from the mArena pool. The allocation is infallible.
@ -518,7 +533,6 @@ protected:
nsHTMLReflowState& aReflowState);
bool CanPlaceFrame(PerFrameData* pfd,
uint8_t aFrameDirection,
bool aNotSafeToBreak,
bool aFrameCanContinueTextRun,
bool aCanRollBackBeforeFrame,
@ -529,15 +543,15 @@ protected:
void PlaceFrame(PerFrameData* pfd,
nsHTMLReflowMetrics& aMetrics);
void VerticalAlignFrames(PerSpanData* psd);
void BlockDirAlignFrames(PerSpanData* psd);
void PlaceTopBottomFrames(PerSpanData* psd,
nscoord aDistanceFromTop,
nscoord aLineHeight);
void PlaceStartEndFrames(PerSpanData* psd,
nscoord aDistanceFromStart,
nscoord aLineBSize);
void RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflowAreas);
bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaWidth);
bool TrimTrailingWhiteSpaceIn(PerSpanData* psd, nscoord* aDeltaISize);
void ComputeJustificationWeights(PerSpanData* psd, int32_t* numSpaces, int32_t* numLetters);

View File

@ -7841,7 +7841,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
iter.SetOriginalOffset(offset);
nscoord xOffsetForTabs = (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TAB) ?
(aLineLayout.GetCurrentFrameXDistanceFromBlock() -
(aLineLayout.GetCurrentFrameInlineDistanceFromBlock() -
lineContainer->GetUsedBorderAndPadding().left)
: -1;
PropertyProvider provider(mTextRun, textStyle, frag, this, iter, length,

View File

@ -13,3 +13,4 @@ sctp updated to version 8263 from SVN on Sun Sep 16 00:48:48 EDT 2012
sctp updated to version 8279 from SVN on Thu Sep 20 18:19:24 EDT 2012
sctp updated to version 8397 from SVN on Wed Jan 9 00:41:16 EST 2013
sctp updated to version 8443 from SVN on Sun Mar 31 09:05:07 EDT 2013
sctp updated to version 8815 from SVN on Tue Mar 4 08:50:51 EST 2014

View File

@ -15,7 +15,6 @@ SOURCES += [
'netinet/sctp_callout.c',
'netinet/sctp_cc_functions.c',
'netinet/sctp_crc32.c',
'netinet/sctp_hashdriver.c',
'netinet/sctp_indata.c',
'netinet/sctp_input.c',
'netinet/sctp_output.c',
@ -54,7 +53,7 @@ LOCAL_INCLUDES += [
'/xpcom/ds',
]
for var in ('SCTP_SIMPLE_ALLOCATOR', 'USE_SCTP_SHA1',
for var in ('SCTP_SIMPLE_ALLOCATOR',
'SCTP_PROCESS_LEVEL_LOCKS', '__Userspace__', 'INET',
'CALLBACK_API', 'SCTP_DEBUG'):
DEFINES[var] = 1

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 246595 2013-02-09 17:26:14Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 254248 2013-08-12 13:52:15Z tuexen $");
#endif
#ifndef _NETINET_SCTP_H_
@ -439,7 +439,7 @@ struct sctp_error_unrecognized_chunk {
/* RFC4895 */
#define SCTP_AUTHENTICATION 0x0f
/* EY nr_sack chunk id*/
#define SCTP_NR_SELECTIVE_ACK 0x10
#define SCTP_NR_SELECTIVE_ACK 0x10
/************0x40 series ***********/
/************0x80 series ***********/
/* RFC5061 */
@ -533,38 +533,38 @@ struct sctp_error_unrecognized_chunk {
/*
* PCB Features (in sctp_features bitmask)
*/
#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x00000001
#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x00000002 /* deprecated */
#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x00000004
#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x00000008
#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x00000010
#define SCTP_PCB_FLAGS_DO_ASCONF 0x00000020
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x00000040
#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x00000080
#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x0000000000000001
#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x0000000000000002 /* deprecated */
#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x0000000000000004
#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x0000000000000008
#define SCTP_PCB_FLAGS_INTERLEAVE_STRMS 0x0000000000000010
#define SCTP_PCB_FLAGS_DO_ASCONF 0x0000000000000020
#define SCTP_PCB_FLAGS_AUTO_ASCONF 0x0000000000000040
#define SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE 0x0000000000000080
/* socket options */
#define SCTP_PCB_FLAGS_NODELAY 0x00000100
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x00000200
#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x00000400 /* deprecated */
#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x00000800
#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x00001000
#define SCTP_PCB_FLAGS_RECVPEERERR 0x00002000
#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x00004000 /* deprecated */
#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x00008000
#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x00010000
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x00020000
#define SCTP_PCB_FLAGS_AUTHEVNT 0x00040000
#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x00080000
#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x00100000
#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x00400000
#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x00800000
#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS 0x01000000
#define SCTP_PCB_FLAGS_PORTREUSE 0x02000000
#define SCTP_PCB_FLAGS_DRYEVNT 0x04000000
#define SCTP_PCB_FLAGS_RECVRCVINFO 0x08000000
#define SCTP_PCB_FLAGS_RECVNXTINFO 0x10000000
#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x20000000
#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x40000000
#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x80000000
#define SCTP_PCB_FLAGS_NODELAY 0x0000000000000100
#define SCTP_PCB_FLAGS_AUTOCLOSE 0x0000000000000200
#define SCTP_PCB_FLAGS_RECVDATAIOEVNT 0x0000000000000400 /* deprecated */
#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x0000000000000800
#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x0000000000001000
#define SCTP_PCB_FLAGS_RECVPEERERR 0x0000000000002000
#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x0000000000004000 /* deprecated */
#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x0000000000008000
#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x0000000000010000
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x0000000000020000
#define SCTP_PCB_FLAGS_AUTHEVNT 0x0000000000040000
#define SCTP_PCB_FLAGS_STREAM_RESETEVNT 0x0000000000080000
#define SCTP_PCB_FLAGS_NO_FRAGMENT 0x0000000000100000
#define SCTP_PCB_FLAGS_EXPLICIT_EOR 0x0000000000400000
#define SCTP_PCB_FLAGS_NEEDS_MAPPED_V4 0x0000000000800000
#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS 0x0000000001000000
#define SCTP_PCB_FLAGS_PORTREUSE 0x0000000002000000
#define SCTP_PCB_FLAGS_DRYEVNT 0x0000000004000000
#define SCTP_PCB_FLAGS_RECVRCVINFO 0x0000000008000000
#define SCTP_PCB_FLAGS_RECVNXTINFO 0x0000000010000000
#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x0000000020000000
#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x0000000040000000
#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x0000000080000000
/*-
* mobility_features parameters (by micchie).Note

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 246595 2013-02-09 17:26:14Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 257803 2013-11-07 17:08:09Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -155,7 +155,10 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_store;
struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
uint16_t param_length;
#endif
struct sockaddr *sa;
int zero_address = 0;
int bad_address = 0;
@ -171,8 +174,9 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
aparam_length = ntohs(aph->ph.param_length);
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
sa = (struct sockaddr *)&sa_store;
switch (param_type) {
#ifdef INET
@ -305,7 +309,10 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_store;
struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
uint16_t param_length;
#endif
struct sockaddr *sa;
int zero_address = 0;
int result;
@ -321,8 +328,9 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
aparam_length = ntohs(aph->ph.param_length);
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
sa = (struct sockaddr *)&sa_store;
switch (param_type) {
#ifdef INET
@ -437,7 +445,10 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_store;
struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
uint16_t param_length;
#endif
struct sockaddr *sa;
int zero_address = 0;
#ifdef INET
@ -452,8 +463,9 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
aparam_length = ntohs(aph->ph.param_length);
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
sa = (struct sockaddr *)&sa_store;
switch (param_type) {
#ifdef INET
@ -873,10 +885,12 @@ sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
static uint32_t
sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
{
#if defined(INET) || defined(INET6)
uint16_t param_type, param_length;
param_type = ntohs(ph->param_type);
param_length = ntohs(ph->param_length);
#endif
switch (sa->sa_family) {
#ifdef INET6
case AF_INET6:
@ -887,7 +901,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
v6addr = (struct sctp_ipv6addr_param *)ph;
if ((param_type == SCTP_IPV6_ADDRESS) &&
param_length == sizeof(struct sctp_ipv6addr_param) &&
(param_length == sizeof(struct sctp_ipv6addr_param)) &&
(memcmp(&v6addr->addr, &sin6->sin6_addr,
sizeof(struct in6_addr)) == 0)) {
return (1);
@ -903,7 +917,7 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
v4addr = (struct sctp_ipv4addr_param *)ph;
if ((param_type == SCTP_IPV4_ADDRESS) &&
param_length == sizeof(struct sctp_ipv4addr_param) &&
(param_length == sizeof(struct sctp_ipv4addr_param)) &&
(memcmp(&v4addr->addr, &sin->sin_addr,
sizeof(struct in_addr)) == 0)) {
return (1);
@ -1206,7 +1220,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
uint16_t type)
{
struct sctp_asconf_addr *aa, *aa_next;
struct sockaddr *sa;
/* make sure the request isn't already in the queue */
TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
@ -1269,7 +1282,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
sa = (struct sockaddr *)sin6;
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@ -1285,7 +1297,6 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
struct sockaddr_in *sin;
sin= (struct sockaddr_in *)&ifa->address.sa;
sa = (struct sockaddr *)sin;
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@ -1308,13 +1319,13 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
if (type == SCTP_ADD_IP_ADDRESS) {
SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
} else if (type == SCTP_DEL_IP_ADDRESS) {
SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
} else {
SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
}
}
#endif
@ -2609,7 +2620,8 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
/* get the parameter length */
p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
/* will it fit in current chunk? */
if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) {
if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
(SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
/* won't fit, so we're done with this chunk */
break;
}
@ -2730,7 +2742,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
/* chain it all together */
SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
*retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
acp->ch.chunk_length = ntohs(*retlen);
acp->ch.chunk_length = htons(*retlen);
return (m_asconf_chk);
}

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 243882 2012-12-05 08:04:20Z glebius $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 257804 2013-11-07 18:50:11Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -335,10 +335,6 @@ sctp_generate_random_key(uint32_t keylen)
{
sctp_key_t *new_key;
/* validate keylen */
if (keylen > SCTP_AUTH_RANDOM_SIZE_MAX)
keylen = SCTP_AUTH_RANDOM_SIZE_MAX;
new_key = sctp_alloc_key(keylen);
if (new_key == NULL) {
/* out of memory */
@ -376,7 +372,7 @@ sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
uint32_t i;
uint32_t key1len, key2len;
uint8_t *key_1, *key_2;
uint8_t temp[SCTP_AUTH_RANDOM_SIZE_MAX];
uint8_t val1, val2;
/* sanity/length check */
key1len = sctp_get_keylen(key1);
@ -388,38 +384,24 @@ sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
else if (key2len == 0)
return (1);
if (key1len != key2len) {
if (key1len >= key2len)
maxlen = key1len;
else
maxlen = key2len;
bzero(temp, maxlen);
if (key1len < maxlen) {
/* prepend zeroes to key1 */
bcopy(key1->key, temp + (maxlen - key1len), key1len);
key_1 = temp;
key_2 = key2->key;
} else {
/* prepend zeroes to key2 */
bcopy(key2->key, temp + (maxlen - key2len), key2len);
key_1 = key1->key;
key_2 = temp;
}
if (key1len < key2len) {
maxlen = key2len;
} else {
maxlen = key1len;
key_1 = key1->key;
key_2 = key2->key;
}
key_1 = key1->key;
key_2 = key2->key;
/* check for numeric equality */
for (i = 0; i < maxlen; i++) {
if (*key_1 > *key_2)
return (1);
else if (*key_1 < *key_2)
return (-1);
key_1++;
key_2++;
/* left-pad with zeros */
val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
if (val1 > val2) {
return (1);
} else if (val1 < val2) {
return (-1);
}
}
/* keys are equal value, so check lengths */
if (key1len == key2len)
return (0);
@ -703,16 +685,12 @@ sctp_auth_add_hmacid(sctp_hmaclist_t *list, uint16_t hmac_id)
"SCTP: HMAC id list full, ignoring add %u\n", hmac_id);
return (-1);
}
#if defined(SCTP_SUPPORT_HMAC_SHA256)
if ((hmac_id != SCTP_AUTH_HMAC_ID_SHA1) &&
#ifdef HAVE_SHA224
(hmac_id != SCTP_AUTH_HMAC_ID_SHA224) &&
(hmac_id != SCTP_AUTH_HMAC_ID_SHA256)) {
#else
if (hmac_id != SCTP_AUTH_HMAC_ID_SHA1) {
#endif
#ifdef HAVE_SHA2
(hmac_id != SCTP_AUTH_HMAC_ID_SHA256) &&
(hmac_id != SCTP_AUTH_HMAC_ID_SHA384) &&
(hmac_id != SCTP_AUTH_HMAC_ID_SHA512) &&
#endif
1) {
return (-1);
}
/* Now is it already in the list */
@ -752,11 +730,18 @@ sctp_default_supported_hmaclist(void)
{
sctp_hmaclist_t *new_list;
#if defined(SCTP_SUPPORT_HMAC_SHA256)
new_list = sctp_alloc_hmaclist(2);
#else
new_list = sctp_alloc_hmaclist(1);
#endif
if (new_list == NULL)
return (NULL);
(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
#if defined(SCTP_SUPPORT_HMAC_SHA256)
/* We prefer SHA256, so list it first */
(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA256);
#endif
(void)sctp_auth_add_hmacid(new_list, SCTP_AUTH_HMAC_ID_SHA1);
return (new_list);
}
@ -812,19 +797,13 @@ int
sctp_verify_hmac_param (struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
{
uint32_t i;
uint16_t hmac_id;
uint32_t sha1_supported = 0;
for (i = 0; i < num_hmacs; i++) {
hmac_id = ntohs(hmacs->hmac_ids[i]);
if (hmac_id == SCTP_AUTH_HMAC_ID_SHA1)
sha1_supported = 1;
if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) {
return (0);
}
}
/* all HMAC id's are supported */
if (sha1_supported == 0)
return (-1);
else
return (0);
return (-1);
}
sctp_authinfo_t *
@ -878,17 +857,9 @@ sctp_get_hmac_digest_len(uint16_t hmac_algo)
switch (hmac_algo) {
case SCTP_AUTH_HMAC_ID_SHA1:
return (SCTP_AUTH_DIGEST_LEN_SHA1);
#ifdef HAVE_SHA224
case SCTP_AUTH_HMAC_ID_SHA224:
return (SCTP_AUTH_DIGEST_LEN_SHA224);
#endif
#ifdef HAVE_SHA2
#if defined(SCTP_SUPPORT_HMAC_SHA256)
case SCTP_AUTH_HMAC_ID_SHA256:
return (SCTP_AUTH_DIGEST_LEN_SHA256);
case SCTP_AUTH_HMAC_ID_SHA384:
return (SCTP_AUTH_DIGEST_LEN_SHA384);
case SCTP_AUTH_HMAC_ID_SHA512:
return (SCTP_AUTH_DIGEST_LEN_SHA512);
#endif
default:
/* unknown HMAC algorithm: can't do anything */
@ -901,16 +872,10 @@ sctp_get_hmac_block_len(uint16_t hmac_algo)
{
switch (hmac_algo) {
case SCTP_AUTH_HMAC_ID_SHA1:
#ifdef HAVE_SHA224
case SCTP_AUTH_HMAC_ID_SHA224:
#endif
return (64);
#ifdef HAVE_SHA2
#if defined(SCTP_SUPPORT_HMAC_SHA256)
case SCTP_AUTH_HMAC_ID_SHA256:
return (64);
case SCTP_AUTH_HMAC_ID_SHA384:
case SCTP_AUTH_HMAC_ID_SHA512:
return (128);
#endif
case SCTP_AUTH_HMAC_ID_RSVD:
default:
@ -927,21 +892,11 @@ sctp_hmac_init(uint16_t hmac_algo, sctp_hash_context_t *ctx)
{
switch (hmac_algo) {
case SCTP_AUTH_HMAC_ID_SHA1:
SHA1_Init(&ctx->sha1);
SCTP_SHA1_INIT(&ctx->sha1);
break;
#ifdef HAVE_SHA224
case SCTP_AUTH_HMAC_ID_SHA224:
break;
#endif
#ifdef HAVE_SHA2
#if defined(SCTP_SUPPORT_HMAC_SHA256)
case SCTP_AUTH_HMAC_ID_SHA256:
SHA256_Init(&ctx->sha256);
break;
case SCTP_AUTH_HMAC_ID_SHA384:
SHA384_Init(&ctx->sha384);
break;
case SCTP_AUTH_HMAC_ID_SHA512:
SHA512_Init(&ctx->sha512);
SCTP_SHA256_INIT(&ctx->sha256);
break;
#endif
case SCTP_AUTH_HMAC_ID_RSVD:
@ -957,21 +912,11 @@ sctp_hmac_update(uint16_t hmac_algo, sctp_hash_context_t *ctx,
{
switch (hmac_algo) {
case SCTP_AUTH_HMAC_ID_SHA1:
SHA1_Update(&ctx->sha1, text, textlen);
SCTP_SHA1_UPDATE(&ctx->sha1, text, textlen);
break;
#ifdef HAVE_SHA224
case SCTP_AUTH_HMAC_ID_SHA224:
break;
#endif
#ifdef HAVE_SHA2
#if defined(SCTP_SUPPORT_HMAC_SHA256)
case SCTP_AUTH_HMAC_ID_SHA256:
SHA256_Update(&ctx->sha256, text, textlen);
break;
case SCTP_AUTH_HMAC_ID_SHA384:
SHA384_Update(&ctx->sha384, text, textlen);
break;
case SCTP_AUTH_HMAC_ID_SHA512:
SHA512_Update(&ctx->sha512, text, textlen);
SCTP_SHA256_UPDATE(&ctx->sha256, text, textlen);
break;
#endif
case SCTP_AUTH_HMAC_ID_RSVD:
@ -987,22 +932,11 @@ sctp_hmac_final(uint16_t hmac_algo, sctp_hash_context_t *ctx,
{
switch (hmac_algo) {
case SCTP_AUTH_HMAC_ID_SHA1:
SHA1_Final(digest, &ctx->sha1);
SCTP_SHA1_FINAL(digest, &ctx->sha1);
break;
#ifdef HAVE_SHA224
case SCTP_AUTH_HMAC_ID_SHA224:
break;
#endif
#ifdef HAVE_SHA2
#if defined(SCTP_SUPPORT_HMAC_SHA256)
case SCTP_AUTH_HMAC_ID_SHA256:
SHA256_Final(digest, &ctx->sha256);
break;
case SCTP_AUTH_HMAC_ID_SHA384:
/* SHA384 is truncated SHA512 */
SHA384_Final(digest, &ctx->sha384);
break;
case SCTP_AUTH_HMAC_ID_SHA512:
SHA512_Final(digest, &ctx->sha512);
SCTP_SHA256_FINAL(digest, &ctx->sha256);
break;
#endif
case SCTP_AUTH_HMAC_ID_RSVD:

View File

@ -32,33 +32,28 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 235828 2012-05-23 11:26:28Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 257804 2013-11-07 18:50:11Z tuexen $");
#endif
#ifndef _NETINET_SCTP_AUTH_H_
#define _NETINET_SCTP_AUTH_H_
#include <netinet/sctp_os.h>
/* digest lengths */
#define SCTP_AUTH_DIGEST_LEN_SHA1 20
#define SCTP_AUTH_DIGEST_LEN_SHA224 28
#define SCTP_AUTH_DIGEST_LEN_SHA256 32
#define SCTP_AUTH_DIGEST_LEN_SHA384 48
#define SCTP_AUTH_DIGEST_LEN_SHA512 64
#define SCTP_AUTH_DIGEST_LEN_MAX 64
#define SCTP_AUTH_DIGEST_LEN_MAX SCTP_AUTH_DIGEST_LEN_SHA256
/* random sizes */
#define SCTP_AUTH_RANDOM_SIZE_DEFAULT 32
#define SCTP_AUTH_RANDOM_SIZE_REQUIRED 32
#define SCTP_AUTH_RANDOM_SIZE_MAX 256
/* union of all supported HMAC algorithm contexts */
typedef union sctp_hash_context {
SHA1_CTX sha1;
#ifdef HAVE_SHA2
SHA256_CTX sha256;
SHA384_CTX sha384;
SHA512_CTX sha512;
SCTP_SHA1_CTX sha1;
#if defined(SCTP_SUPPORT_HMAC_SHA256)
SCTP_SHA256_CTX sha256;
#endif
} sctp_hash_context_t;

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 239035 2012-08-04 08:03:30Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 258765 2013-11-30 12:51:19Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -48,11 +48,11 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 239035 2012-08-04 08:03:30Z
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_indata.h>
#if !defined(__Userspace_os_Windows)
#if defined(ANDROID)
#include <unistd.h>
#include <ifaddrs-android-ext.h>
#else
#if defined(__FreeBSD__)
#include <sys/unistd.h>
#endif
#endif
@ -165,20 +165,13 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
SCTP_IPI_ITERATOR_WQ_UNLOCK();
#if defined(__Userspace__)
sctp_wakeup_iterator();
#if !defined(__Userspace_os_Windows)
pthread_exit(NULL);
#else
ExitThread(0);
#endif
return (NULL);
#else
wakeup(&sctp_it_ctl.iterator_flags);
thread_terminate(current_thread());
#endif
#ifdef INVARIANTS
panic("Hmm. thread_terminate() continues...");
#endif
#if defined(__Userspace__)
return (NULL);
#endif
#endif
}
@ -186,46 +179,35 @@ sctp_iterator_thread(void *v SCTP_UNUSED)
void
sctp_startup_iterator(void)
{
static int called = 0;
#if defined(__FreeBSD__) || (defined(__Userspace__) && !defined(__Userspace_os_Windows))
int ret;
#endif
if (called) {
if (sctp_it_ctl.thread_proc) {
/* You only get one */
return;
}
/* init the iterator head */
called = 1;
sctp_it_ctl.iterator_running = 0;
sctp_it_ctl.iterator_flags = 0;
sctp_it_ctl.cur_it = NULL;
/* Initialize global locks here, thus only once. */
SCTP_ITERATOR_LOCK_INIT();
SCTP_IPI_ITERATOR_WQ_INIT();
TAILQ_INIT(&sctp_it_ctl.iteratorhead);
#if defined(__FreeBSD__)
#if __FreeBSD_version <= 701000
ret = kthread_create(sctp_iterator_thread,
kthread_create(sctp_iterator_thread,
#else
ret = kproc_create(sctp_iterator_thread,
kproc_create(sctp_iterator_thread,
#endif
(void *)NULL,
&sctp_it_ctl.thread_proc,
RFPROC,
SCTP_KTHREAD_PAGES,
SCTP_KTRHEAD_NAME);
(void *)NULL,
&sctp_it_ctl.thread_proc,
RFPROC,
SCTP_KTHREAD_PAGES,
SCTP_KTRHEAD_NAME);
#elif defined(__APPLE__)
(void)kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
kernel_thread_start((thread_continue_t)sctp_iterator_thread, NULL, &sctp_it_ctl.thread_proc);
#elif defined(__Userspace__)
#if defined(__Userspace_os_Windows)
if ((sctp_it_ctl.thread_proc = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&sctp_iterator_thread, NULL, 0, NULL)) == NULL) {
SCTP_PRINTF("ERROR; Creating sctp_iterator_thread failed\n");
}
#else
if ((ret = pthread_create(&sctp_it_ctl.thread_proc, NULL, &sctp_iterator_thread, NULL))) {
SCTP_PRINTF("ERROR; return code from sctp_iterator_thread pthread_create() is %d\n", ret);
}
if (pthread_create(&sctp_it_ctl.thread_proc, NULL, &sctp_iterator_thread, NULL)) {
#endif
SCTP_PRINTF("ERROR: Creating sctp_iterator_thread failed.\n");
}
#endif
}
@ -341,11 +323,13 @@ sctp_is_vmware_interface(struct ifnet *ifn)
static void
sctp_init_ifns_for_vrf(int vrfid)
{
#if defined(INET) || defined(INET6)
struct ifaddrs *ifa;
struct sctp_ifa *sctp_ifa;
DWORD Err, AdapterAddrsSize;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapterAddrs6, pAdapt;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast;
#endif
#ifdef INET
AdapterAddrsSize = 0;
@ -372,6 +356,9 @@ sctp_init_ifns_for_vrf(int vrfid)
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
if (IN4_ISLINKLOCAL_ADDRESS(&(((struct sockaddr_in *)(pUnicast->Address.lpSockaddr))->sin_addr))) {
continue;
}
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
ifa->ifa_name = strdup(pAdapt->AdapterName);
ifa->ifa_flags = pAdapt->Flags;
@ -407,17 +394,17 @@ sctp_init_ifns_for_vrf(int vrfid)
}
}
/* Allocate memory from sizing information */
if ((pAdapterAddrs6 = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) {
SCTP_PRINTF("Memory allocation error!\n");
return;
}
/* Get actual adapter information */
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs6, &AdapterAddrsSize)) != ERROR_SUCCESS) {
if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) {
SCTP_PRINTF("GetAdaptersV6Addresses() failed with error code %d\n", Err);
return;
}
/* Enumerate through each returned adapter and save its information */
for (pAdapt = pAdapterAddrs6; pAdapt; pAdapt = pAdapt->Next) {
for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) {
if (pAdapt->IfType == IF_TYPE_IEEE80211 || pAdapt->IfType == IF_TYPE_ETHERNET_CSMACD) {
for (pUnicast = pAdapt->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
ifa = (struct ifaddrs*)malloc(sizeof(struct ifaddrs));
@ -440,18 +427,15 @@ sctp_init_ifns_for_vrf(int vrfid)
}
}
}
if (pAdapterAddrs6)
FREE(pAdapterAddrs6);
if (pAdapterAddrs)
FREE(pAdapterAddrs);
#endif
}
#elif defined(__Userspace__)
static void
sctp_init_ifns_for_vrf(int vrfid)
{
/* __Userspace__ TODO struct ifaddr is defined in net/if_var.h
* This struct contains struct ifnet, which is also defined in
* net/if_var.h. Currently a zero byte if_var.h file is present for Linux boxes
*/
#if defined(INET) || defined(INET6)
int rc;
struct ifaddrs *ifa = NULL;
struct sctp_ifa *sctp_ifa;
@ -461,24 +445,39 @@ sctp_init_ifns_for_vrf(int vrfid)
if (rc != 0) {
return;
}
for (ifa = g_interfaces; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) {
continue;
}
#if !defined(INET)
if (ifa->ifa_addr->sa_family != AF_INET6) {
/* non inet6 skip */
continue;
}
#elif !defined(INET6)
if (ifa->ifa_addr->sa_family != AF_INET) {
/* non inet skip */
continue;
}
#else
if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) {
/* non inet/inet6 skip */
continue;
}
#endif
#if defined(INET6)
if ((ifa->ifa_addr->sa_family == AF_INET6) &&
IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
/* skip unspecifed addresses */
continue;
}
#endif
#if defined(INET)
if (ifa->ifa_addr->sa_family == AF_INET &&
((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) {
continue;
}
#endif
ifa_flags = 0;
sctp_ifa = sctp_add_addr_to_vrf(vrfid,
ifa,
@ -493,6 +492,7 @@ sctp_init_ifns_for_vrf(int vrfid)
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
}
}
#endif
}
#endif
@ -830,12 +830,12 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
return (NULL);
}
if (allonebuf == 0)
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
else
mbuf_threshold = 1;
if (space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
if ((int)space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
MCLGET(m, how);
if (m == NULL) {
return (NULL);

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 243157 2012-11-16 19:39:10Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 256556 2013-10-15 20:21:27Z tuexen $");
#endif
#ifndef _NETINET_SCTP_CONSTANTS_H_
@ -557,9 +557,6 @@ extern void getwintimeofday(struct timeval *tv);
/* How long a cookie lives in milli-seconds */
#define SCTP_DEFAULT_COOKIE_LIFE 60000
/* resource limit of streams */
#define MAX_SCTP_STREAMS 2048
/* Maximum the mapping array will grow to (TSN mapping array) */
#define SCTP_MAPPING_ARRAY 512
@ -702,6 +699,7 @@ extern void getwintimeofday(struct timeval *tv);
/* How many streams I request initally by default */
#define SCTP_OSTREAM_INITIAL 10
#define SCTP_ISTREAM_INITIAL 2048
/*
* How many smallest_mtu's need to increase before a window update sack is
@ -776,7 +774,6 @@ extern void getwintimeofday(struct timeval *tv);
/* small chunk store for looking at chunk_list in auth */
#define SCTP_SMALL_CHUNK_STORE 260
#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */
#define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */
#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */
@ -1050,6 +1047,10 @@ extern void getwintimeofday(struct timeval *tv);
(((uint8_t *)&(a)->s_addr)[2] == 0) && \
(((uint8_t *)&(a)->s_addr)[3] == 1))
#define IN4_ISLINKLOCAL_ADDRESS(a) \
((((uint8_t *)&(a)->s_addr)[0] == 169) && \
(((uint8_t *)&(a)->s_addr)[1] == 254))
#if defined(__Userspace__)
#if defined(__Userspace_os_Windows)
#define SCTP_GETTIME_TIMEVAL(x) getwintimeofday(x)

View File

@ -40,6 +40,8 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.c 235828 2012-05-23 11:26:28Z tu
#include <netinet/sctp_crc32.h>
#include <netinet/sctp_pcb.h>
#if !defined(SCTP_WITH_NO_CSUM)
#if defined(__FreeBSD__) && __FreeBSD_version >= 800000
#else
/**
@ -708,8 +710,6 @@ calculate_crc32c(uint32_t crc32c,
}
#endif /* FreeBSD < 80000 || other OS */
#if !defined(SCTP_WITH_NO_CSUM)
static uint32_t
sctp_finalize_crc32c(uint32_t crc32c)
{
@ -785,6 +785,7 @@ sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
#endif /* !defined(SCTP_WITH_NO_CSUM) */
#if defined(__FreeBSD__)
void
sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
{
@ -813,4 +814,5 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
*(uint32_t *) (m->m_data + offset) = checksum;
#endif
}
#endif

View File

@ -42,7 +42,9 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_crc32.h 235828 2012-05-23 11:26:28Z tu
#if !defined(SCTP_WITH_NO_CSUM)
uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
#endif
#if defined(__FreeBSD__)
void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
#endif
#endif /* _KERNEL */
#if defined(__Userspace__)
#if !defined(SCTP_WITH_NO_CSUM)

View File

@ -1,89 +0,0 @@
/*-
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* c) Neither the name of Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_dtrace_declare.h 235828 2012-05-23 11:26:28Z tuexen $");
#endif
#ifndef _NETINET_SCTP_DTRACE_DECLARE_H_
#define _NETINET_SCTP_DTRACE_DECLARE_H_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
#include "opt_kdtrace.h"
#include <sys/kernel.h>
#include <sys/sdt.h>
/* Declare the SCTP provider */
SDT_PROVIDER_DECLARE(sctp);
/* The probes we have so far: */
/* One to track a net's cwnd */
/* initial */
SDT_PROBE_DECLARE(sctp, cwnd, net, init);
/* update at a ack -- increase */
SDT_PROBE_DECLARE(sctp, cwnd, net, ack);
/* update at a fast retransmit -- decrease */
SDT_PROBE_DECLARE(sctp, cwnd, net, fr);
/* update at a time-out -- decrease */
SDT_PROBE_DECLARE(sctp, cwnd, net, to);
/* update at a burst-limit -- decrease */
SDT_PROBE_DECLARE(sctp, cwnd, net, bl);
/* update at a ECN -- decrease */
SDT_PROBE_DECLARE(sctp, cwnd, net, ecn);
/* update at a Packet-Drop -- decrease */
SDT_PROBE_DECLARE(sctp, cwnd, net, pd);
/* Rttvar probe declaration */
SDT_PROBE_DECLARE(sctp, cwnd, net, rttvar);
SDT_PROBE_DECLARE(sctp, cwnd, net, rttstep);
/* One to track an associations rwnd */
SDT_PROBE_DECLARE(sctp, rwnd, assoc, val);
/* One to track a net's flight size */
SDT_PROBE_DECLARE(sctp, flightsize, net, val);
/* One to track an associations flight size */
SDT_PROBE_DECLARE(sctp, flightsize, assoc, val);
#else
/* All other platforms not defining dtrace probes */
#ifndef SDT_PROBE
#define SDT_PROBE(a, b, c, d, e, f, g, h, i)
#endif
#endif
#endif

View File

@ -1,243 +0,0 @@
/*-
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* c) Neither the name of Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_dtrace_define.h 235828 2012-05-23 11:26:28Z tuexen $");
#endif
#ifndef _NETINET_SCTP_DTRACE_DEFINE_H_
#define _NETINET_SCTP_DTRACE_DEFINE_H_
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
#include "opt_kdtrace.h"
#include <sys/kernel.h>
#include <sys/sdt.h>
SDT_PROVIDER_DEFINE(sctp);
/********************************************************/
/* Cwnd probe - tracks changes in the congestion window on a netp */
/********************************************************/
/* Initial */
SDT_PROBE_DEFINE(sctp, cwnd, net, init, init);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 4, "int");
/* ACK-INCREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, ack, ack);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 4, "int");
/* ACK-INCREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, rttvar, rttvar);
/* The Vtag << 32 | localport << 16 | remoteport */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 0, "uint64_t");
/* obw | nbw */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 1, "uint64_t");
/* bwrtt | newrtt */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 2, "uint64_t");
/* flight */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 3, "uint64_t");
/* (cwnd << 32) | point << 16 | retval(0/1) */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttvar, 4, "uint64_t");
SDT_PROBE_DEFINE(sctp, cwnd, net, rttstep, rttstep);
/* The Vtag << 32 | localport << 16 | remoteport */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 0, "uint64_t");
/* obw | nbw */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 1, "uint64_t");
/* bwrtt | nrtt */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 2, "uint64_t");
/* cwnd_saved | stepcnt << 16 | oldstep */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 3, "uint64_t");
/* (cwnd << 32) | point << 16 | retval(0/1) */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, rttstep, 4, "uint64_t");
/* FastRetransmit-DECREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, fr, fr);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 4, "int");
/* TimeOut-DECREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, to, to);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 4, "int");
/* BurstLimit-DECREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, bl, bl);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 4, "int");
/* ECN-DECREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, ecn, ecn);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 4, "int");
/* PacketDrop-DECREASE */
SDT_PROBE_DEFINE(sctp, cwnd, net, pd, pd);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 2, "uintptr_t");
/* The old value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 4, "int");
/********************************************************/
/* Rwnd probe - tracks changes in the receiver window for an assoc */
/********************************************************/
SDT_PROBE_DEFINE(sctp, rwnd, assoc, val, val);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 1, "uint32_t");
/* The up/down amount */
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 2, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 3, "int");
/********************************************************/
/* flight probe - tracks changes in the flight size on a net or assoc */
/********************************************************/
SDT_PROBE_DEFINE(sctp, flightsize, net, val, val);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 1, "uint32_t");
/* The pointer to the struct sctp_nets * changing */
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 2, "uintptr_t");
/* The up/down amount */
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 3, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 4, "int");
/********************************************************/
/* The total flight version */
/********************************************************/
SDT_PROBE_DEFINE(sctp, flightsize, assoc, val, val);
/* The Vtag for this end */
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 0, "uint32_t");
/* The port number of the local side << 16 | port number of remote
* in network byte order.
*/
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 1, "uint32_t");
/* The up/down amount */
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 2, "int");
/* The new value of the cwnd */
SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 3, "int");
#else /* to #if Freebsd */
/* All other platforms not defining dtrace probes */
#ifndef SDT_PROBE
#define SDT_PROBE(a, b, c, d, e, f, g, h, i)
#endif
#endif
#endif

View File

@ -1,284 +0,0 @@
/*-
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* c) Neither the name of Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_os.h>
#include <netinet/sctp_constants.h>
#ifdef USE_MD5
#include <crypto/md5.h>
#else
#if !defined(__APPLE__) && !defined(__Userspace__)
#include <netinet/sctp_sha1.h>
#endif
#endif /* USE_MD5 */
#include <netinet/sctp_hashdriver.h>
/*
* Main driver for SCTP's hashing. passing a two pointers and two lengths,
* returning a digest pointer filled. The md5 code was taken directly from
* the RFC (2104) so to understand it you may want to go look at the RFC
* referenced in the SCTP spec. We did modify this code to either user OURs
* implementation of SLA1 or the MD5 that comes from its RFC. SLA1 may have
* IPR issues so you need to check in to this if you wish to use it... Or at
* least that is what the FIP-180.1 web page says.
*/
void
sctp_hash_digest(char *key, int key_len, char *text, int text_len,
unsigned char *digest)
{
#ifdef USE_MD5
md5_ctxt context;
#else
#if defined(__APPLE__) || defined(__Userspace__)
SHA1_CTX context;
#else
struct sha1_context context;
#endif
#endif /* USE_MD5 */
/* inner padding - key XORd with ipad */
unsigned char k_ipad[65];
/* outer padding - key XORd with opad */
unsigned char k_opad[65];
unsigned char tk[20];
int i;
if (key_len > 64) {
#ifdef USE_MD5
md5_ctxt tctx;
MD5Init(&tctx);
MD5Update(&tctx, key, key_len);
MD5Final(tk, &tctx);
key = tk;
key_len = 16;
#else
#if defined(__APPLE__) || defined(__Userspace__)
SHA1_CTX tctx;
#else
struct sha1_context tctx;
#endif
SHA1_Init(&tctx);
SHA1_Update(&tctx, (unsigned char *)key, key_len);
SHA1_Final(tk, &tctx);
key = (char *)tk;
key_len = 20;
#endif /* USE_MD5 */
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times and text is the data
* being protected
*/
/* start out by storing key in pads */
bzero(k_ipad, sizeof k_ipad);
bzero(k_opad, sizeof k_opad);
bcopy(key, k_ipad, key_len);
bcopy(key, k_opad, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
/*
* perform inner MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 1st pass */
MD5Update(&context, k_ipad, 64); /* start with inner pad */
MD5Update(&context, text, text_len); /* then text of datagram */
MD5Final(digest, &context); /* finish up 1st pass */
#else
SHA1_Init(&context); /* init context for 1st pass */
SHA1_Update(&context, k_ipad, 64); /* start with inner pad */
SHA1_Update(&context,
(unsigned char *)text,
text_len); /* then text of datagram */
SHA1_Final(digest, &context); /* finish up 1st pass */
#endif /* USE_MD5 */
/*
* perform outer MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 2nd pass */
MD5Update(&context, k_opad, 64); /* start with outer pad */
MD5Update(&context, digest, 16); /* then results of 1st hash */
MD5Final(digest, &context); /* finish up 2nd pass */
#else
SHA1_Init(&context); /* init context for 2nd pass */
SHA1_Update(&context, k_opad, 64); /* start with outer pad */
SHA1_Update(&context,
(unsigned char *)digest, 20); /* then results of 1st hash */
SHA1_Final(digest, &context); /* finish up 2nd pass */
#endif /* USE_MD5 */
}
void
sctp_hash_digest_m(char *key, int key_len, struct mbuf *m, int offset,
unsigned char *digest)
{
struct mbuf *m_at;
#ifdef USE_MD5
md5_ctxt context;
#else
#if defined(__APPLE__) || defined(__Userspace__)
SHA1_CTX context;
#else
struct sha1_context context;
#endif
#endif /* USE_MD5 */
/* inner padding - key XORd with ipad */
unsigned char k_ipad[65];
/* outer padding - key XORd with opad */
unsigned char k_opad[65];
unsigned char tk[20];
int i;
if (key_len > 64) {
#ifdef USE_MD5
md5_ctxt tctx;
MD5Init(&tctx);
MD5Update(&tctx, key, key_len);
MD5Final(tk, &tctx);
key = tk;
key_len = 16;
#else
#if defined(__APPLE__) || defined(__Userspace__)
SHA1_CTX tctx;
#else
struct sha1_context tctx;
#endif
SHA1_Init(&tctx);
SHA1_Update(&tctx, (unsigned char *)key, key_len);
SHA1_Final(tk, &tctx);
key = (char *)tk;
key_len = 20;
#endif /* USE_MD5 */
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times and text is the data
* being protected
*/
/* start out by storing key in pads */
bzero(k_ipad, sizeof k_ipad);
bzero(k_opad, sizeof k_opad);
bcopy(key, k_ipad, key_len);
bcopy(key, k_opad, key_len);
/* XOR key with ipad and opad values */
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
/* find the correct mbuf and offset into mbuf */
m_at = m;
while ((m_at != NULL) && (offset > SCTP_BUF_LEN(m_at))) {
offset -= SCTP_BUF_LEN(m_at); /* update remaining offset left */
m_at = SCTP_BUF_NEXT(m_at);
}
/*
* perform inner MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 1st pass */
MD5Update(&context, k_ipad, 64); /* start with inner pad */
/******/
while (m_at != NULL) {
/* then text of datagram... */
MD5Update(&context, mtod(m_at, char *)+offset,
SCTP_BUF_LEN(m_at) - offset);
/* only offset on the first mbuf */
offset = 0;
m_at = SCTP_BUF_NEXT(m_at);
}
/******/
MD5Final(digest, &context); /* finish up 1st pass */
#else
SHA1_Init(&context); /* init context for 1st pass */
SHA1_Update(&context, k_ipad, 64); /* start with inner pad */
/******/
while (m_at != NULL) {
/* then text of datagram */
SHA1_Update(&context, mtod(m_at, unsigned char *)+offset,
SCTP_BUF_LEN(m_at) - offset);
/* only offset on the first mbuf */
offset = 0;
m_at = SCTP_BUF_NEXT(m_at);
}
/******/
SHA1_Final(digest, &context); /* finish up 1st pass */
#endif /* USE_MD5 */
/*
* perform outer MD5
*/
#ifdef USE_MD5
MD5Init(&context); /* init context for 2nd pass */
MD5Update(&context, k_opad, 64); /* start with outer pad */
MD5Update(&context, digest, 16); /* then results of 1st hash */
MD5Final(digest, &context); /* finish up 2nd pass */
#else
SHA1_Init(&context); /* init context for 2nd pass */
SHA1_Update(&context, k_opad, 64); /* start with outer pad */
SHA1_Update(&context, digest, 20); /* then results of 1st hash */
SHA1_Final(digest, &context); /* finish up 2nd pass */
#endif /* USE_MD5 */
}

View File

@ -1,46 +0,0 @@
/*-
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* a) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* b) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* c) Neither the name of Cisco Systems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#ifndef _NETINET_SCTP_HASHDRIVER_H_
#define _NETINET_SCTP_HASHDRIVER_H_
void sctp_hash_digest(char *, int, char *, int, unsigned char *);
void sctp_hash_digest_m(char *, int, struct mbuf *, int, unsigned char *);
#endif

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 246674 2013-02-11 13:57:03Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 258228 2013-11-16 16:09:09Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -806,13 +806,12 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc)
* but should we?
*/
if (stcb->sctp_socket) {
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
stcb->sctp_ep->partial_delivery_point);
} else {
pd_point = stcb->sctp_ep->partial_delivery_point;
}
if (sctp_is_all_msg_on_reasm(asoc, &tsize) || (tsize >= pd_point)) {
/*
* Yes, we setup to start reception, by
* backing down the TSN just in case we
@ -1432,7 +1431,6 @@ sctp_does_tsn_belong_to_reasm(struct sctp_association *asoc,
return (0);
}
static int
sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct mbuf **m, int offset, struct sctp_data_chunk *ch, int chk_length,
@ -1742,7 +1740,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
sctp_alloc_a_readq(stcb, control);
sctp_build_readq_entry_mac(control, stcb, asoc->context, net, tsn,
protocol_id,
stcb->asoc.context,
strmno, strmseq,
chunk_flags,
dmbuf);
@ -1804,7 +1801,6 @@ failed_express_del:
asoc->highest_tsn_inside_nr_map = tsn;
}
SCTP_STAT_INCR(sctps_recvexpressm);
control->sinfo_tsn = tsn;
asoc->tsn_last_delivered = tsn;
asoc->fragment_flags = chunk_flags;
asoc->tsn_of_pdapi_last_delivered = tsn;
@ -1868,7 +1864,6 @@ failed_express_del:
sctp_alloc_a_readq(stcb, control);
sctp_build_readq_entry_mac(control, stcb, asoc->context, net, tsn,
protocol_id,
stcb->asoc.context,
strmno, strmseq,
chunk_flags,
dmbuf);
@ -2506,7 +2501,7 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
* delivery queue and something can be delivered.
*/
if (stcb->sctp_socket) {
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket),
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
stcb->sctp_ep->partial_delivery_point);
} else {
pd_point = stcb->sctp_ep->partial_delivery_point;
@ -3695,6 +3690,7 @@ sctp_fs_audit(struct sctp_association *asoc)
struct sctp_tmit_chunk *chk;
int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0;
int entry_flight, entry_cnt, ret;
entry_flight = asoc->total_flight;
entry_cnt = asoc->total_flight_count;
ret = 0;
@ -4743,7 +4739,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
}
}
TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
if (tp1->pr_sctp_on) {
if (PR_SCTP_ENABLED(tp1->flags)) {
if (asoc->pr_sctp_cnt != 0)
asoc->pr_sctp_cnt--;
}

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 237715 2012-06-28 16:01:08Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.h 252585 2013-07-03 18:48:43Z tuexen $");
#endif
#ifndef _NETINET_SCTP_INDATA_H_
@ -49,14 +49,14 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
struct mbuf *dm);
#define sctp_build_readq_entry_mac(_ctl, in_it, a, net, tsn, ppid, context, stream_no, stream_seq, flags, dm) do { \
#define sctp_build_readq_entry_mac(_ctl, in_it, context, net, tsn, ppid, stream_no, stream_seq, flags, dm) do { \
if (_ctl) { \
atomic_add_int(&((net)->ref_count), 1); \
(_ctl)->sinfo_stream = stream_no; \
(_ctl)->sinfo_ssn = stream_seq; \
(_ctl)->sinfo_flags = (flags << 8); \
(_ctl)->sinfo_ppid = ppid; \
(_ctl)->sinfo_context = a; \
(_ctl)->sinfo_context = context; \
(_ctl)->sinfo_timetolive = 0; \
(_ctl)->sinfo_tsn = tsn; \
(_ctl)->sinfo_cumtsn = tsn; \

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 246595 2013-02-09 17:26:14Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 262252 2014-02-20 20:14:43Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -412,9 +412,10 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
}
SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
}
asoc->streamincnt = ntohs(init->num_outbound_streams);
if (asoc->streamincnt > MAX_SCTP_STREAMS) {
asoc->streamincnt = MAX_SCTP_STREAMS;
if (asoc->max_inbound_streams > ntohs(init->num_outbound_streams)) {
asoc->streamincnt = ntohs(init->num_outbound_streams);
} else {
asoc->streamincnt = asoc->max_inbound_streams;
}
SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt *
sizeof(struct sctp_stream_in), SCTP_M_STRMI);
@ -426,11 +427,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
for (i = 0; i < asoc->streamincnt; i++) {
asoc->strmin[i].stream_no = i;
asoc->strmin[i].last_sequence_delivered = 0xffff;
/*
* U-stream ranges will be set when the cookie is unpacked.
* Or for the INIT sender they are un set (if pr-sctp not
* supported) when the INIT-ACK arrives.
*/
TAILQ_INIT(&asoc->strmin[i].inqueue);
asoc->strmin[i].delivery_started = 0;
}
@ -468,7 +464,6 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
/* First verify that we have no illegal param's */
abort_flag = 0;
op_err = NULL;
op_err = sctp_arethere_unrecognized_parameters(m,
(offset + sizeof(struct sctp_init_chunk)),
@ -1068,12 +1063,13 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
SCTP_SOCKET_UNLOCK(so, 1);
#endif
}
/* are the queues empty? */
#ifdef INVARIANTS
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_report_all_outbound(stcb, 0, 0, SCTP_SO_NOT_LOCKED);
panic("Queues are not empty when handling SHUTDOWN-ACK");
}
#endif
/* stop the timer */
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_9);
/* send SHUTDOWN-COMPLETE */
@ -1614,7 +1610,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
switch SCTP_GET_STATE(asoc) {
switch (SCTP_GET_STATE(asoc)) {
case SCTP_STATE_COOKIE_WAIT:
case SCTP_STATE_COOKIE_ECHOED:
/*
@ -1926,20 +1922,24 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
cookie->tie_tag_peer_vtag == asoc->peer_vtag_nonce &&
cookie->tie_tag_peer_vtag != 0) {
struct sctpasochead *head;
if (asoc->peer_supports_nat) {
/* This is a gross gross hack.
* just call the cookie_new code since we
* are allowing a duplicate association. I hope
* this works...
*/
return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
sh, cookie, cookie_len,
inp, netp, init_src,notification,
auth_skipped, auth_offset, auth_len,
#if defined(__FreeBSD__)
use_mflowid, mflowid,
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
#endif
vrf_id, port));
if (asoc->peer_supports_nat) {
/* This is a gross gross hack.
* Just call the cookie_new code since we
* are allowing a duplicate association.
* I hope this works...
*/
return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
sh, cookie, cookie_len,
inp, netp, init_src,notification,
auth_skipped, auth_offset, auth_len,
#if defined(__FreeBSD__)
use_mflowid, mflowid,
#endif
vrf_id, port));
}
/*
* case A in Section 5.2.4 Table 2: XXMM (peer restarted)
@ -1992,6 +1992,10 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
asoc->mapping_array_size);
}
SCTP_TCB_UNLOCK(stcb);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
so = SCTP_INP_SO(stcb->sctp_ep);
SCTP_SOCKET_LOCK(so, 1);
#endif
SCTP_INP_INFO_WLOCK();
SCTP_INP_WLOCK(stcb->sctp_ep);
SCTP_TCB_LOCK(stcb);
@ -1999,7 +2003,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* send up all the data */
SCTP_TCB_SEND_LOCK(stcb);
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_NOT_LOCKED);
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].chunks_on_queues = 0;
stcb->asoc.strmout[i].stream_no = i;
@ -2021,11 +2025,15 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
*/
LIST_INSERT_HEAD(head, stcb, sctp_asocs);
/* process the INIT info (peer's info) */
SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_INP_WUNLOCK(stcb->sctp_ep);
SCTP_INP_INFO_WUNLOCK();
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
asoc->total_flight = 0;
asoc->total_flight_count = 0;
/* process the INIT info (peer's info) */
retval = sctp_process_init(init_cp, stcb);
if (retval < 0) {
if (how_indx < sizeof(asoc->cookie_how))
@ -3335,13 +3343,14 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
/* notify upper layer protocol */
if (stcb->sctp_socket) {
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_DOWN, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
/* are the queues empty? they should be */
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_report_all_outbound(stcb, 0, 0, SCTP_SO_NOT_LOCKED);
}
}
#ifdef INVARIANTS
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
}
#endif
/* stop the timer */
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT+SCTP_LOC_22);
SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
@ -3599,7 +3608,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
}
void
sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t * list)
sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
{
uint32_t i;
uint16_t temp;
@ -3627,18 +3636,13 @@ sctp_reset_in_stream(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *
}
static void
sctp_reset_out_streams(struct sctp_tcb *stcb, int number_entries, uint16_t * list)
sctp_reset_out_streams(struct sctp_tcb *stcb, uint32_t number_entries, uint16_t *list)
{
int i;
uint32_t i;
uint16_t temp;
if (number_entries == 0) {
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].next_sequence_send = 0;
}
} else if (number_entries) {
if (number_entries > 0) {
for (i = 0; i < number_entries; i++) {
uint16_t temp;
temp = ntohs(list[i]);
if (temp >= stcb->asoc.streamoutcnt) {
/* no such stream */
@ -3646,6 +3650,10 @@ sctp_reset_out_streams(struct sctp_tcb *stcb, int number_entries, uint16_t * lis
}
stcb->asoc.strmout[temp].next_sequence_send = 0;
}
} else {
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].next_sequence_send = 0;
}
}
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
}
@ -3732,7 +3740,7 @@ sctp_handle_stream_reset_response(struct sctp_tcb *stcb,
struct sctp_association *asoc = &stcb->asoc;
struct sctp_tmit_chunk *chk;
struct sctp_stream_reset_out_request *srparam;
int number_entries;
uint32_t number_entries;
if (asoc->stream_reset_outstanding == 0) {
/* duplicate */
@ -4079,7 +4087,7 @@ sctp_handle_str_reset_add_strm(struct sctp_tcb *stcb, struct sctp_tmit_chunk *ch
if (!(asoc->local_strreset_support & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
} else if ((num_stream > stcb->asoc.max_inbound_streams) ||
(num_stream > 0xffff)) {
(num_stream > 0xffff)) {
/* We must reject it they ask for to many */
denied:
stcb->asoc.last_reset_action[0] = SCTP_STREAM_RESET_RESULT_DENIED;
@ -4691,8 +4699,10 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
if ((ch->chunk_type == SCTP_ABORT_ASSOCIATION) ||
(ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) ||
(ch->chunk_type == SCTP_PACKET_DROPPED)) {
if ((vtag_in == asoc->my_vtag) ||
((ch->chunk_flags & SCTP_HAD_NO_TCB) &&
/* Take the T-bit always into account. */
if ((((ch->chunk_flags & SCTP_HAD_NO_TCB) == 0) &&
(vtag_in == asoc->my_vtag)) ||
(((ch->chunk_flags & SCTP_HAD_NO_TCB) == SCTP_HAD_NO_TCB) &&
(vtag_in == asoc->peer_vtag))) {
/* this is valid */
} else {
@ -5704,6 +5714,7 @@ sctp_validate_no_locks(struct sctp_inpcb *inp)
{
#ifndef __APPLE__
struct sctp_tcb *lstcb;
LIST_FOREACH(lstcb, &inp->sctp_asoc_list, sctp_tcblist) {
if (mtx_owned(&lstcb->tcb_mtx)) {
panic("Own lock on stcb at return from input");
@ -5853,7 +5864,11 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
#ifdef INET
case AF_INET:
if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
#if defined(__FreeBSD__) && (__FreeBSD_version > 1000036)
IPSECSTAT_INC(ips_in_polvio);
#else
MODULE_GLOBAL(ipsec4stat).in_polvio++;
#endif
SCTP_STAT_INCR(sctps_hdrops);
goto out;
}
@ -5862,7 +5877,11 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
#ifdef INET6
case AF_INET6:
if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
#if defined(__FreeBSD__) && (__FreeBSD_version > 1000036)
IPSEC6STAT_INC(ips_in_polvio);
#else
MODULE_GLOBAL(ipsec6stat).in_polvio++;
#endif
SCTP_STAT_INCR(sctps_hdrops);
goto out;
}
@ -6209,7 +6228,13 @@ sctp_input(i_pak, va_alist)
}
#endif
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
#if __FreeBSD_version > 1000049
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
"sctp_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
m->m_pkthdr.len,
if_name(m->m_pkthdr.rcvif),
(int)m->m_pkthdr.csum_flags, CSUM_BITS);
#elif __FreeBSD_version >= 800000
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
"sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
m->m_pkthdr.len,

View File

@ -44,8 +44,6 @@
#if defined(__Userspace_os_Windows)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2ipdef.h>
#include <ws2def.h>
#include <iphlpapi.h>
#include <Mswsock.h>
#include <Windows.h>
@ -63,6 +61,10 @@ typedef struct
CRITICAL_SECTION waiters_count_lock;
HANDLE events_[C_MAX_EVENTS];
} userland_cond_t;
void InitializeXPConditionVariable(userland_cond_t *);
void DeleteXPConditionVariable(userland_cond_t *);
int SleepXPConditionVariable(userland_cond_t *, userland_mutex_t *);
void WakeAllXPConditionVariable(userland_cond_t *);
#define InitializeConditionVariable(cond) InitializeXPConditionVariable(cond)
#define DeleteConditionVariable(cond) DeleteXPConditionVariable(cond)
#define SleepConditionVariableCS(cond, mtx, time) SleepXPConditionVariable(cond, mtx)
@ -75,27 +77,32 @@ typedef HANDLE userland_thread_t;
#define ADDRESS_FAMILY unsigned __int8
#define IPVERSION 4
#define MAXTTL 255
/* VS2010 comes with stdint.h */
#if _MSC_VER >= 1600
#include <stdint.h>
#else
#define uint64_t unsigned __int64
#define uint32_t unsigned __int32
#define int32_t __int32
#define uint16_t unsigned __int16
#define int16_t __int16
#define uint8_t unsigned __int8
#define int8_t __int8
#endif
#ifndef _SIZE_T_DEFINED
#define size_t __int32
#endif
#define u_long unsigned __int64
#define u_int unsigned __int32
#define uint32_t unsigned __int32
#define u_int32_t unsigned __int32
#define int32_t __int32
#define int16_t __int16
#define uint16_t unsigned __int16
#define u_int16_t unsigned __int16
#define uint8_t unsigned __int8
#define u_int8_t unsigned __int8
#define int8_t __int8
#define u_char unsigned char
#define n_short unsigned __int16
#define u_short unsigned __int16
#define ssize_t __int64
#define size_t __int32
#define in_addr_t unsigned __int32
#define in_port_t unsigned __int16
#define n_time unsigned __int32
#define sa_family_t unsigned __int8
#define ssize_t __int64
#define IFNAMSIZ 64
#define __func__ __FUNCTION__
@ -210,8 +217,10 @@ typedef HANDLE userland_thread_t;
typedef char* caddr_t;
int Win_getifaddrs(struct ifaddrs**);
#define getifaddrs(interfaces) (int)Win_getifaddrs(interfaces)
#define if_nametoindex(x) (int)win_if_nametoindex(x)
int win_if_nametoindex(const char *);
#define if_nametoindex(x) win_if_nametoindex(x)
#define bzero(buf, len) memset(buf, 0, len)
#define bcopy(srcKey, dstKey, len) memcpy(dstKey, srcKey, len)
@ -226,12 +235,22 @@ typedef char* caddr_t;
#ifdef CMSG_DATA
#undef CMSG_DATA
#endif
/*
* The following definitions should apply iff WINVER < 0x0600
* but that check doesn't work in all cases. So be more pedantic...
*/
#define CMSG_DATA(x) WSA_CMSG_DATA(x)
#define CMSG_ALIGN(x) WSA_CMSGDATA_ALIGN(x)
#if WINVER < 0x0600
#ifndef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(x) WSA_CMSG_FIRSTHDR(x)
#endif
#ifndef CMSG_NXTHDR
#define CMSG_NXTHDR(x, y) WSA_CMSG_NXTHDR(x, y)
#endif
#ifndef CMSG_SPACE
#define CMSG_SPACE(x) WSA_CMSG_SPACE(x)
#endif
#ifndef CMSG_LEN
#define CMSG_LEN(x) WSA_CMSG_LEN(x)
#endif
@ -383,7 +402,7 @@ struct udphdr {
#else /* !defined(Userspace_os_Windows) */
#include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
#include <sys/socket.h>
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(ANDROID)
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(ANDROID)
#include <pthread.h>
#endif
typedef pthread_mutex_t userland_mutex_t;
@ -397,7 +416,9 @@ typedef pthread_t userland_thread_t;
#define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */
#if !defined(__Userspace_os_FreeBSD)
struct mtx {int dummy;};
#if !defined(__Userspace_os_NetBSD)
struct selinfo {int dummy;};
#endif
struct sx {int dummy;};
#endif
@ -463,7 +484,7 @@ struct sx {int dummy;};
/* for getifaddrs */
#include <sys/types.h>
#if !defined(__Userspace_os_Windows)
#if !defined(ANDROID)
#if !defined(ANDROID) && (defined(INET) || defined(INET6))
#include <ifaddrs.h>
#endif
@ -500,7 +521,7 @@ struct sx {int dummy;};
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#endif
#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) ||defined(__Userspace_os_Windows)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Windows)
#include "user_ip6_var.h"
#else
#include <netinet6/ip6_var.h>
@ -518,6 +539,8 @@ struct sx {int dummy;};
#include <sys/filedesc.h>
#endif
#include "netinet/sctp_sha1.h"
#if __FreeBSD_version >= 700000
#include <netinet/ip_options.h>
#endif
@ -582,21 +605,21 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
#if defined(SCTP_DEBUG)
#include <netinet/sctp_constants.h>
#define SCTPDBG(level, ...) \
{ \
do { \
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \
SCTP_PRINTF(__VA_ARGS__); \
} \
} while (0); \
#define SCTPDBG(level, ...) \
{ \
do { \
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \
SCTP_PRINTF(__VA_ARGS__); \
} \
} while (0); \
}
#define SCTPDBG_ADDR(level, addr) \
{ \
do { \
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \
sctp_print_address(addr); \
} \
} while (0); \
#define SCTPDBG_ADDR(level, addr) \
{ \
do { \
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level ) { \
sctp_print_address(addr); \
} \
} while (0); \
}
#else
#define SCTPDBG(level, ...)
@ -654,17 +677,17 @@ MALLOC_DECLARE(SCTP_M_SOCKOPT);
/*
* general memory allocation
*/
#define SCTP_MALLOC(var, type, size, name) \
do { \
MALLOC(var, type, size, name, M_NOWAIT); \
} while (0)
#define SCTP_MALLOC(var, type, size, name) \
do { \
MALLOC(var, type, size, name, M_NOWAIT); \
} while (0)
#define SCTP_FREE(var, type) FREE(var, type)
#define SCTP_MALLOC_SONAME(var, type, size) \
do { \
MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \
} while (0)
#define SCTP_MALLOC_SONAME(var, type, size) \
do { \
MALLOC(var, type, size, M_SONAME, (M_WAITOK | M_ZERO)); \
} while (0)
#define SCTP_FREE_SONAME(var) FREE(var, M_SONAME)
@ -978,72 +1001,18 @@ int sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af);
/* This is re-pulse ourselves for sendbuf */
#define SCTP_ZERO_COPY_SENDQ_EVENT(inp, so)
/*
* SCTP AUTH
*/
/* USE_SCTP_SHA1 is defined if you need sctp_sha1.[ch]. SHA1_* functions are defined
* there. On Linux, they are also defined in libcrypto.a once you install
* the libssl-dev package (on Ubuntu, at least).
*/
/* #define USE_SCTP_SHA1 */
/* #define HAVE_SHA2 sha2.h exists on Linux? */
#define SCTP_READ_RANDOM(buf, len) read_random(buf, len)
#ifdef USE_SCTP_SHA1
#include <netinet/sctp_sha1.h>
#else
#if 0 /*this was old _KERNEL code... */
#include <crypto/sha1.h>
/* map standard crypto API names */
#define SHA1_Init SHA1Init
#define SHA1_Update SHA1Update
#define SHA1_Final(x,y) SHA1Final((caddr_t)x, y)
#endif
#endif
#if defined(HAVE_SHA2)
#include <crypto/sha2/sha2.h>
#endif
#if 0
/* going to have to port so generic across OS's... */
#if 1 /* openssl header files on FreeBSD 6.3 on Emulab and libssl-dev for Ubuntu */
#include <openssl/md5.h>
#include <openssl/sha.h>
/* libssl-dev calls this SHA_CTX, but it's refered to as SHA1_CTX within the
* SCTP stack code so here we typedef (or macro?) to equate the two.
*/
typedef SHA_CTX SHA1_CTX;
#else /* only _KERNEL? */
#include <sys/md5.h>
/* map standard crypto API names */
#define MD5_Init MD5Init
#define MD5_Update MD5Update
#define MD5_Final MD5Final
#endif
#endif
#define SCTP_SHA1_CTX struct sctp_sha1_context
#define SCTP_SHA1_INIT sctp_sha1_init
#define SCTP_SHA1_UPDATE sctp_sha1_update
#define SCTP_SHA1_FINAL(x,y) sctp_sha1_final((unsigned char *)x, y)
/* start OOTB only stuff */
/* TODO IFT_LOOP is in net/if_types.h on Linux */
#define IFT_LOOP 0x18
/* sctp_pcb.h */
/* typedef int SHA1_CTX; */
/* typedef int MD5_CTX; */
#ifdef HAVE_SHA2
typedef int SHA256_CTX;
typedef int SHA384_CTX;
typedef int SHA512_CTX;
#endif
#if defined(__Userspace_os_Windows)
#define SHUT_RD 1
@ -1070,6 +1039,11 @@ struct sockaddr_conn {
void *sconn_addr;
};
/*
* SCTP protocol specific mbuf flags.
*/
#define M_NOTIFICATION M_PROTO5 /* SCTP notification */
/*
* IP output routines
*/
@ -1117,9 +1091,11 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
/* with the current included files, this is defined in Linux but
* in FreeBSD, it is behind a _KERNEL in sys/socket.h ...
*/
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
/* stolen from /usr/include/sys/socket.h */
#define CMSG_ALIGN(n) _ALIGN(n)
#elif defined(__Userspace_os_NetBSD)
#define CMSG_ALIGN(n) (((n) + __ALIGNBYTES) & ~__ALIGNBYTES)
#elif defined(__Userspace_os_Darwin)
#if !defined(__DARWIN_ALIGNBYTES)
#define __DARWIN_ALIGNBYTES (sizeof(__darwin_size_t) - 1)
@ -1156,14 +1132,21 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int a
#endif
#if defined(__Userspace_os_Linux)
#if !defined(TAILQ_FOREACH_SAFE)
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = ((head)->tqh_first); \
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#endif
#if !defined(LIST_FOREACH_SAFE)
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = ((head)->lh_first); \
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
(var) = (tvar))
#endif
#endif
#if defined(__Userspace_os_DragonFly)
#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
#define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE
#endif
#endif

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 246687 2013-02-11 21:02:49Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 262252 2014-02-20 20:14:43Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -1972,9 +1972,11 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
static struct mbuf *
sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
{
#if defined(INET) || defined(INET6)
struct sctp_paramhdr *parmh;
struct mbuf *mret;
uint16_t plen;
#endif
switch (ifa->address.sa.sa_family) {
#ifdef INET
@ -1990,6 +1992,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
default:
return (m);
}
#if defined(INET) || defined(INET6)
if (M_TRAILINGSPACE(m) >= plen) {
/* easy side we just drop it on the end */
parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
@ -2052,6 +2055,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
*len += plen;
}
return (mret);
#endif
}
@ -3446,7 +3450,11 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
return (found);
}
m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_prinfo), (caddr_t)&prinfo);
sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
if (prinfo.pr_policy != SCTP_PR_SCTP_NONE) {
sndrcvinfo->sinfo_timetolive = prinfo.pr_value;
} else {
sndrcvinfo->sinfo_timetolive = 0;
}
sndrcvinfo->sinfo_flags |= prinfo.pr_policy;
break;
case SCTP_AUTHINFO:
@ -3628,7 +3636,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
static struct sctp_tcb *
sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
in_port_t port,
uint16_t port,
struct mbuf *control,
struct sctp_nets **net_p,
int *error)
@ -3734,7 +3742,6 @@ sctp_add_cookie(struct mbuf *init, int init_offset,
int sig_offset;
uint16_t cookie_sz;
mret = NULL;
mret = sctp_get_mbuf_for_msg((sizeof(struct sctp_state_cookie) +
sizeof(struct sctp_paramhdr)), 0,
M_NOWAIT, 1, MT_DATA);
@ -3931,7 +3938,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
struct sctphdr *sctphdr;
int packet_length;
int ret;
#if defined(INET) || defined(INET6)
uint32_t vrf_id;
#endif
#if defined(INET) || defined(INET6)
#if !defined(__Panda__)
struct mbuf *o_pak;
@ -3957,12 +3966,13 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctp_m_freem(m);
return (EFAULT);
}
#if defined(INET) || defined(INET6)
if (stcb) {
vrf_id = stcb->asoc.vrf_id;
} else {
vrf_id = inp->def_vrf_id;
}
#endif
/* fill in the HMAC digest for any AUTH chunk in the packet */
if ((auth != NULL) && (stcb != NULL)) {
sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb, auth_keyid);
@ -4338,7 +4348,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
* This means especially, that it is not set at the
* SCTP layer. So use the value from the IP layer.
*/
#if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
flowlabel = ntohl(inp->ip_inp.inp.inp_flow);
#else
flowlabel = ntohl(((struct in6pcb *)inp)->in6p_flowinfo);
#endif
}
flowlabel &= 0x000fffff;
len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
@ -4418,7 +4432,11 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
* SCTP layer. So use the value from the IP layer.
*/
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Panda__) || defined(__Windows__) || defined(__Userspace__)
#if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
tos_value = (ntohl(inp->ip_inp.inp.inp_flow) >> 20) & 0xff;
#else
tos_value = (ntohl(((struct in6pcb *)inp)->in6p_flowinfo) >> 20) & 0xff;
#endif
#endif
}
tos_value &= 0xfc;
@ -4736,6 +4754,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
#else
if (ro->ro_rt) {
RTFREE(ro->ro_rt);
ro->ro_rt = NULL;
}
#endif
} else {
@ -4805,8 +4824,12 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctphdr->dest_port = dest_port;
sctphdr->v_tag = v_tag;
sctphdr->checksum = 0;
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_sendnocrc);
#else
sctphdr->checksum = sctp_calculate_cksum(m, 0);
SCTP_STAT_INCR(sctps_sendswcrc);
#endif
if (tos_value == 0) {
tos_value = inp->ip_inp.inp.inp_ip_tos;
}
@ -4846,9 +4869,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
struct mbuf *m;
struct sctp_nets *net;
struct sctp_init_chunk *init;
#if defined(INET) || defined(INET6)
struct sctp_supported_addr_param *sup_addr;
#endif
struct sctp_adaptation_layer_indication *ali;
struct sctp_supported_chunk_types_param *pr_supported;
struct sctp_paramhdr *ph;
@ -5730,6 +5751,14 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
/*
* We might not overwrite the identification[] completely and on
* some platforms time_entered will contain some padding.
* Therefore zero out the cookie to avoid putting
* uninitialized memory on the wire.
*/
memset(&stc, 0, sizeof(struct sctp_state_cookie));
/* the time I built cookie */
(void)SCTP_GETTIME_TIMEVAL(&stc.time_entered);
@ -5892,6 +5921,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
memcpy(&stc.laddress, &dstconn->sconn_addr, sizeof(void *));
stc.laddr_type = SCTP_CONN_ADDRESS;
/* scope_id is only for v6 */
stc.scope_id = 0;
break;
}
#endif
@ -5987,11 +6017,19 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#if defined(__Userspace__)
case AF_CONN:
sconn = (struct sockaddr_conn *)to;
stc.address[0] = 0;
stc.address[1] = 0;
stc.address[2] = 0;
stc.address[3] = 0;
memcpy(&stc.address, &sconn->sconn_addr, sizeof(void *));
stc.addr_type = SCTP_CONN_ADDRESS;
stc.laddress[0] = 0;
stc.laddress[1] = 0;
stc.laddress[2] = 0;
stc.laddress[3] = 0;
memcpy(&stc.laddress, &sconn->sconn_addr, sizeof(void *));
stc.scope_id = 0;
stc.laddr_type = SCTP_CONN_ADDRESS;
stc.scope_id = 0;
break;
#endif
}
@ -6427,17 +6465,16 @@ sctp_get_frag_point(struct sctp_tcb *stcb,
static void
sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp)
{
sp->pr_sctp_on = 0;
/*
* We assume that the user wants PR_SCTP_TTL if the user
* provides a positive lifetime but does not specify any
* PR_SCTP policy. This is a BAD assumption and causes
* problems at least with the U-Vancovers MPI folks. I will
* change this to be no policy means NO PR-SCTP.
* PR_SCTP policy.
*/
if (PR_SCTP_ENABLED(sp->sinfo_flags)) {
sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
sp->pr_sctp_on = 1;
} else if (sp->timetolive > 0) {
sp->sinfo_flags |= SCTP_PR_SCTP_TTL;
sp->act_flags |= PR_SCTP_POLICY(sp->sinfo_flags);
} else {
return;
}
@ -6774,7 +6811,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
/* TSNH */
return;
}
if ((ca->m) && ca->sndlen) {
if (ca->sndlen > 0) {
m = SCTP_M_COPYM(ca->m, 0, M_COPYALL, M_NOWAIT);
if (m == NULL) {
/* can't copy so we are done */
@ -6803,35 +6840,39 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
}
if (ca->sndrcv.sinfo_flags & SCTP_ABORT) {
/* Abort this assoc with m as the user defined reason */
if (m) {
if (m != NULL) {
SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
} else {
m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
0, M_NOWAIT, 1, MT_DATA);
SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
}
if (m != NULL) {
struct sctp_paramhdr *ph;
SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_NOWAIT);
if (m) {
ph = mtod(m, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
}
/* We add one here to keep the assoc from
* dis-appearing on us.
*/
atomic_add_int(&stcb->asoc.refcnt, 1);
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
/* sctp_abort_an_association calls sctp_free_asoc()
* free association will NOT free it since we
* incremented the refcnt .. we do this to prevent
* it being freed and things getting tricky since
* we could end up (from free_asoc) calling inpcb_free
* which would get a recursive lock call to the
* iterator lock.. But as a consequence of that the
* stcb will return to us un-locked.. since free_asoc
* returns with either no TCB or the TCB unlocked, we
* must relock.. to unlock in the iterator timer :-0
*/
SCTP_TCB_LOCK(stcb);
atomic_add_int(&stcb->asoc.refcnt, -1);
goto no_chunk_output;
ph = mtod(m, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons(sizeof(struct sctp_paramhdr) + ca->sndlen);
}
/* We add one here to keep the assoc from
* dis-appearing on us.
*/
atomic_add_int(&stcb->asoc.refcnt, 1);
sctp_abort_an_association(inp, stcb, m, SCTP_SO_NOT_LOCKED);
/* sctp_abort_an_association calls sctp_free_asoc()
* free association will NOT free it since we
* incremented the refcnt .. we do this to prevent
* it being freed and things getting tricky since
* we could end up (from free_asoc) calling inpcb_free
* which would get a recursive lock call to the
* iterator lock.. But as a consequence of that the
* stcb will return to us un-locked.. since free_asoc
* returns with either no TCB or the TCB unlocked, we
* must relock.. to unlock in the iterator timer :-0
*/
SCTP_TCB_LOCK(stcb);
atomic_add_int(&stcb->asoc.refcnt, -1);
goto no_chunk_output;
} else {
if (m) {
ret = sctp_msg_append(stcb, net, m,
@ -6914,8 +6955,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
if ((sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) &&
(stcb->asoc.total_flight > 0) &&
(un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))
) {
(un_sent < (int)(stcb->asoc.smallest_mtu - SCTP_MIN_OVERHEAD))) {
do_chunk_output = 0;
}
if (do_chunk_output)
@ -7057,13 +7097,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
/* Gather the length of the send */
struct mbuf *mat;
mat = m;
ca->sndlen = 0;
while (m) {
ca->sndlen += SCTP_BUF_LEN(m);
m = SCTP_BUF_NEXT(m);
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
ca->sndlen += SCTP_BUF_LEN(mat);
}
ca->m = mat;
}
ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
@ -7265,8 +7302,8 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_l
static int
sctp_can_we_split_this(struct sctp_tcb *stcb,
uint32_t length,
uint32_t goal_mtu, uint32_t frag_point, int eeor_on)
uint32_t length,
uint32_t goal_mtu, uint32_t frag_point, int eeor_on)
{
/* Make a decision on if I should split a
* msg into multiple parts. This is only asked of
@ -7325,18 +7362,18 @@ sctp_can_we_split_this(struct sctp_tcb *stcb,
static uint32_t
sctp_move_to_outqueue(struct sctp_tcb *stcb,
struct sctp_stream_out *strq,
uint32_t goal_mtu,
uint32_t frag_point,
int *locked,
int *giveup,
int eeor_mode,
int *bail,
int so_locked
struct sctp_stream_out *strq,
uint32_t goal_mtu,
uint32_t frag_point,
int *locked,
int *giveup,
int eeor_mode,
int *bail,
int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
SCTP_UNUSED
#endif
)
)
{
/* Move from the stream to the send_queue keeping track of the total */
struct sctp_association *asoc;
@ -7350,7 +7387,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
SCTP_TCB_LOCK_ASSERT(stcb);
asoc = &stcb->asoc;
one_more_time:
one_more_time:
/*sa_ignore FREED_MEMORY*/
sp = TAILQ_FIRST(&strq->outqueue);
if (sp == NULL) {
@ -7385,11 +7422,11 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
if ((sp->put_last_out == 0) && (sp->discard_rest == 0)) {
SCTP_PRINTF("Gak, put out entire msg with NO end!-1\n");
SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
sp->sender_all_done,
sp->length,
sp->msg_is_complete,
sp->put_last_out,
send_lock_up);
sp->sender_all_done,
sp->length,
sp->msg_is_complete,
sp->put_last_out,
send_lock_up);
}
if ((TAILQ_NEXT(sp, next) == NULL) && (send_lock_up == 0)) {
SCTP_TCB_SEND_LOCK(stcb);
@ -7462,7 +7499,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
sp->msg_is_complete = 1;
}
re_look:
re_look:
length = sp->length;
if (sp->msg_is_complete) {
/* The message is complete */
@ -7561,7 +7598,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
sp->data = sp->tail_mbuf = NULL;
} else {
struct mbuf *m;
dont_do_it:
dont_do_it:
chk->data = SCTP_M_COPYM(sp->data, 0, to_move, M_NOWAIT);
chk->last_mbuf = NULL;
if (chk->data == NULL) {
@ -7779,13 +7816,8 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
}
chk->send_size += pads;
}
/* We only re-set the policy if it is on */
if (sp->pr_sctp_on) {
sctp_set_prsctp_policy(sp);
if (PR_SCTP_ENABLED(chk->flags)) {
asoc->pr_sctp_cnt++;
chk->pr_sctp_on = 1;
} else {
chk->pr_sctp_on = 0;
}
if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) {
/* All done pull and kill the message */
@ -7826,7 +7858,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
strq->chunks_on_queues++;
TAILQ_INSERT_TAIL(&asoc->send_queue, chk, sctp_next);
asoc->send_queue_cnt++;
out_of:
out_of:
if (send_lock_up) {
SCTP_TCB_SEND_UNLOCK(stcb);
}
@ -7980,7 +8012,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
#endif
)
{
/*
/**
* Ok this is the generic chunk service queue. we must do the
* following: - Service the stream queue that is next, moving any
* message (note I must get a complete message i.e. FIRST/MIDDLE and
@ -9331,7 +9363,6 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb)
struct sctp_chunkhdr *hdr;
struct sctp_tmit_chunk *chk;
cookie_ack = NULL;
SCTP_TCB_LOCK_ASSERT(stcb);
cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_NOWAIT, 1, MT_HEADER);
@ -11083,6 +11114,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
struct sctp_abort_chunk *abort;
struct sctp_auth_chunk *auth = NULL;
struct sctp_nets *net;
uint32_t vtag;
uint32_t auth_offset = 0;
uint16_t cause_len, chunk_len, padding_len;
@ -11145,7 +11177,14 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
/* Fill in the ABORT chunk header. */
abort = mtod(m_abort, struct sctp_abort_chunk *);
abort->ch.chunk_type = SCTP_ABORT_ASSOCIATION;
abort->ch.chunk_flags = 0;
if (stcb->asoc.peer_vtag == 0) {
/* This happens iff the assoc is in COOKIE-WAIT state. */
vtag = stcb->asoc.my_vtag;
abort->ch.chunk_flags = SCTP_HAD_NO_TCB;
} else {
vtag = stcb->asoc.peer_vtag;
abort->ch.chunk_flags = 0;
}
abort->ch.chunk_length = htons(chunk_len);
/* Add padding, if necessary. */
if (padding_len > 0) {
@ -11157,7 +11196,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
(void)sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
m_out, auth_offset, auth, stcb->asoc.authinfo.active_keyid, 1, 0, 0,
stcb->sctp_ep->sctp_lport, stcb->rport, htonl(stcb->asoc.peer_vtag),
stcb->sctp_ep->sctp_lport, stcb->rport, htonl(vtag),
stcb->asoc.primary_destination->port, NULL,
#if defined(__FreeBSD__)
0, 0,
@ -11232,7 +11271,10 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *shout;
struct sctp_chunkhdr *ch;
struct udphdr *udp;
int len, cause_len, padding_len, ret;
int len, cause_len, padding_len;
#if defined(INET) || defined(INET6)
int ret;
#endif
#ifdef INET
#if defined(__APPLE__) || defined(__Panda__)
sctp_route_t ro;
@ -11508,6 +11550,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
/* Free the route if we got one back */
if (ro.ro_rt) {
RTFREE(ro.ro_rt);
ro.ro_rt = NULL;
}
#else
SCTP_IP_OUTPUT(ret, o_pak, NULL, NULL, vrf_id);
@ -11564,8 +11607,12 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
struct sockaddr_conn *sconn;
sconn = (struct sockaddr_conn *)src;
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_sendnocrc);
#else
shout->checksum = sctp_calculate_cksum(mout, 0);
SCTP_STAT_INCR(sctps_sendswcrc);
#endif
#ifdef SCTP_PACKET_LOGGING
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
sctp_packet_log(mout);
@ -11574,7 +11621,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
/* Don't alloc/free for each packet */
if ((buffer = malloc(len)) != NULL) {
m_copydata(mout, 0, len, buffer);
ret = SCTP_BASE_VAR(conn_output)(sconn->sconn_addr, buffer, len, 0, 0);
SCTP_BASE_VAR(conn_output)(sconn->sconn_addr, buffer, len, 0, 0);
free(buffer);
}
sctp_m_freem(mout);

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 246687 2013-02-11 21:02:49Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 258765 2013-11-30 12:51:19Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -68,14 +68,6 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 246687 2013-02-11 21:02:49Z tuex
#include <sys/unistd.h>
#endif
#if defined(__Userspace__)
#if !defined(__Userspace_os_Windows)
#if defined(ANDROID)
#include <unistd.h>
#include <ifaddrs-android-ext.h>
#else
#include <sys/unistd.h>
#endif
#endif
#include <user_socketvar.h>
#endif
@ -90,8 +82,10 @@ struct sctp_base_info system_base_info;
#endif
#if defined(__Userspace__)
#if defined(INET) || defined(INET6)
struct ifaddrs *g_interfaces;
#endif
#endif
/* FIX: we don't handle multiple link local scopes */
/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
#ifdef INET6
@ -926,8 +920,13 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
static int
sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
{
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
int ipv4_addr_legal, ipv6_addr_legal;
int loopback_scope;
#if defined(INET)
int ipv4_local_scope, ipv4_addr_legal;
#endif
#if defined(INET6)
int local_scope, site_scope, ipv6_addr_legal;
#endif
#if defined(__Userspace__)
int conn_addr_legal;
#endif
@ -936,11 +935,15 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
struct sctp_ifa *sctp_ifa;
loopback_scope = stcb->asoc.scope.loopback_scope;
#if defined(INET)
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
#endif
#if defined(INET6)
local_scope = stcb->asoc.scope.local_scope;
site_scope = stcb->asoc.scope.site_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
#endif
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif
@ -968,7 +971,9 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
*/
continue;
}
if (sctp_ifa->address.sa.sa_family != to->sa_family) {
continue;
}
switch (sctp_ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
@ -2318,8 +2323,11 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
struct sockaddr *dst)
{
struct sctp_paramhdr *phdr, parm_buf;
#if defined(INET) || defined(INET6)
struct sctp_tcb *stcb;
uint32_t ptype, plen;
uint16_t ptype;
#endif
uint16_t plen;
#ifdef INET
struct sockaddr_in sin4;
#endif
@ -2344,13 +2352,14 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
sin6.sin6_port = sh->src_port;
#endif
stcb = NULL;
offset += sizeof(struct sctp_init_chunk);
phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
while (phdr != NULL) {
/* now we must see if we want the parameter */
#if defined(INET) || defined(INET6)
ptype = ntohs(phdr->param_type);
#endif
plen = ntohs(phdr->param_length);
if (plen == 0) {
break;
@ -2534,7 +2543,7 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
if (sh->v_tag) {
/* we only go down this path if vtag is non-zero */
stcb = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag),
inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
if (stcb) {
return (stcb);
}
@ -2550,11 +2559,11 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
}
if (inp_p) {
stcb = sctp_findassociation_addr_sa(src, dst, inp_p, netp,
find_tcp_pool, vrf_id);
find_tcp_pool, vrf_id);
inp = *inp_p;
} else {
stcb = sctp_findassociation_addr_sa(src, dst, &inp, netp,
find_tcp_pool, vrf_id);
find_tcp_pool, vrf_id);
}
SCTPDBG(SCTP_DEBUG_PCB1, "stcb:%p inp:%p\n", (void *)stcb, (void *)inp);
if (stcb == NULL && inp) {
@ -2740,8 +2749,13 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
inp->ip_inp.inp.inp_socket = so;
#ifdef INET6
#if !defined(__Userspace__) && !defined(__Windows__)
if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
if (INP_SOCKAF(so) == AF_INET6) {
if (MODULE_GLOBAL(ip6_auto_flowlabel)) {
inp->ip_inp.inp.inp_flags |= IN6P_AUTOFLOWLABEL;
}
if (MODULE_GLOBAL(ip6_v6only)) {
inp->ip_inp.inp.inp_flags |= IN6P_IPV6_V6ONLY;
}
}
#endif
#endif
@ -2863,7 +2877,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
#if defined(__APPLE__)
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(mtx_grp), SCTP_BASE_INFO(mtx_attr));
inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
if (inp->ip_inp.inp.inpcb_mtx == NULL) {
SCTP_PRINTF("in_pcballoc: can't alloc mutex! so=%p\n", (void *)so);
#ifdef SCTP_MVRF
@ -2872,12 +2886,14 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
so->so_pcb = NULL;
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
SCTP_UNLOCK_EXC(SCTP_BASE_INFO(ipi_ep_mtx));
SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
return (ENOMEM);
}
#elif defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
#else
lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(mtx_grp), SCTP_BASE_INFO(mtx_attr));
lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).ipi_lock_grp, SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
#endif
#endif
SCTP_INP_INFO_WLOCK();
@ -2893,7 +2909,12 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
/* add it to the info area */
LIST_INSERT_HEAD(&SCTP_BASE_INFO(listhead), inp, sctp_list);
#if defined(__APPLE__)
LIST_INSERT_HEAD(&SCTP_BASE_INFO(inplisthead), &inp->ip_inp.inp, inp_list);
inp->ip_inp.inp.inp_pcbinfo = &SCTP_BASE_INFO(sctbinfo);
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).listhead, &inp->ip_inp.inp, inp_list);
#else
LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).ipi_listhead, &inp->ip_inp.inp, inp_list);
#endif
#endif
SCTP_INP_INFO_WUNLOCK();
@ -2927,9 +2948,6 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
m->initial_rto = SCTP_BASE_SYSCTL(sctp_rto_initial_default);
m->initial_init_rto_max = SCTP_BASE_SYSCTL(sctp_init_rto_max_default);
m->sctp_sack_freq = SCTP_BASE_SYSCTL(sctp_sack_freq_default);
m->max_open_streams_intome = MAX_SCTP_STREAMS;
m->max_init_times = SCTP_BASE_SYSCTL(sctp_init_rtx_max_default);
m->max_send_times = SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default);
m->def_net_failure = SCTP_BASE_SYSCTL(sctp_path_rtx_max_default);
@ -2941,6 +2959,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module);
m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module);
m->max_open_streams_intome = SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default);
/* number of streams to pre-open on a association */
m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default);
@ -3139,7 +3158,9 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
/* bind a ep to a socket address */
struct sctppcbhead *head;
struct sctp_inpcb *inp, *inp_tmp;
#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
struct inpcb *ip_inp;
#endif
int port_reuse_active = 0;
int bindall;
#ifdef SCTP_MVRF
@ -3153,7 +3174,9 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
error = 0;
bindall = 1;
inp = (struct sctp_inpcb *)so->so_pcb;
#if defined(INET) || (defined(INET6) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__APPLE__)
ip_inp = (struct inpcb *)so->so_pcb;
#endif
#ifdef SCTP_DEBUG
if (addr) {
SCTPDBG(SCTP_DEBUG_PCB1, "Bind called port: %d\n",
@ -4382,7 +4405,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
#endif
if (set_scope) {
#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
stcb->ipv4_local_scope = 1;
stcb->asoc.scope.ipv4_local_scope = 1;
#else
if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
stcb->asoc.scope.ipv4_local_scope = 1;
@ -4588,6 +4611,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
#endif
SCTP_RTALLOC((sctp_route_t *)&net->ro, stcb->asoc.vrf_id);
#if !defined(__Userspace__)
if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
/* Get source address */
net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
@ -4617,6 +4641,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
}
}
}
#endif
if (net->mtu == 0) {
switch (newaddr->sa_family) {
#ifdef INET
@ -5056,6 +5081,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
asoc->nr_mapping_array = NULL;
}
SCTP_DECR_ASOC_COUNT();
SCTP_TCB_UNLOCK(stcb);
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
LIST_REMOVE(stcb, sctp_tcbasocidhash);
@ -5191,23 +5217,21 @@ sctp_delete_from_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
int i;
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
if (!LIST_EMPTY(chain)) {
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
twait_block->vtag_block[i].lport = 0;
twait_block->vtag_block[i].rport = 0;
found = 1;
break;
}
}
if (found)
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
twait_block->vtag_block[i].lport = 0;
twait_block->vtag_block[i].rport = 0;
found = 1;
break;
}
}
if (found)
break;
}
}
@ -5221,19 +5245,17 @@ sctp_is_in_timewait(uint32_t tag, uint16_t lport, uint16_t rport)
SCTP_INP_INFO_WLOCK();
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
if (!LIST_EMPTY(chain)) {
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
found = 1;
break;
}
}
if (found)
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
found = 1;
break;
}
}
if (found)
break;
}
SCTP_INP_INFO_WUNLOCK();
return (found);
@ -5255,42 +5277,40 @@ sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t
(void)SCTP_GETTIME_TIMEVAL(&now);
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
set = 0;
if (!LIST_EMPTY(chain)) {
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
/* Block(s) present, lets find space, and expire on the fly */
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if ((twait_block->vtag_block[i].v_tag == 0) &&
!set) {
twait_block->vtag_block[i].tv_sec_at_expire =
now.tv_sec + time;
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if ((twait_block->vtag_block[i].v_tag == 0) &&
!set) {
twait_block->vtag_block[i].tv_sec_at_expire =
now.tv_sec + time;
twait_block->vtag_block[i].v_tag = tag;
twait_block->vtag_block[i].lport = lport;
twait_block->vtag_block[i].rport = rport;
set = 1;
} else if ((twait_block->vtag_block[i].v_tag) &&
((long)twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
/* Audit expires this guy */
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
twait_block->vtag_block[i].lport = 0;
twait_block->vtag_block[i].rport = 0;
if (set == 0) {
/* Reuse it for my new tag */
twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
twait_block->vtag_block[i].v_tag = tag;
twait_block->vtag_block[i].lport = lport;
twait_block->vtag_block[i].rport = rport;
set = 1;
} else if ((twait_block->vtag_block[i].v_tag) &&
((long)twait_block->vtag_block[i].tv_sec_at_expire < now.tv_sec)) {
/* Audit expires this guy */
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
twait_block->vtag_block[i].lport = 0;
twait_block->vtag_block[i].rport = 0;
if (set == 0) {
/* Reuse it for my new tag */
twait_block->vtag_block[i].tv_sec_at_expire = now.tv_sec + time;
twait_block->vtag_block[i].v_tag = tag;
twait_block->vtag_block[i].lport = lport;
twait_block->vtag_block[i].rport = rport;
set = 1;
}
}
}
if (set) {
/*
* We only do up to the block where we can
* place our tag for audits
*/
break;
}
}
if (set) {
/*
* We only do up to the block where we can
* place our tag for audits
*/
break;
}
}
/* Need to add a new block to chain */
@ -5876,6 +5896,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
/* Insert new items here :> */
/* Get rid of LOCK */
SCTP_TCB_UNLOCK(stcb);
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
if (from_inpcbfree == SCTP_NORMAL_PROC) {
@ -6601,6 +6622,25 @@ sctp_pcb_init()
LIST_INIT(&SCTP_BASE_INFO(listhead));
#if defined(__APPLE__)
LIST_INIT(&SCTP_BASE_INFO(inplisthead));
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
SCTP_BASE_INFO(sctbinfo).listhead = &SCTP_BASE_INFO(inplisthead);
SCTP_BASE_INFO(sctbinfo).mtx_grp_attr = lck_grp_attr_alloc_init();
lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
SCTP_BASE_INFO(sctbinfo).mtx_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
SCTP_BASE_INFO(sctbinfo).mtx_attr = lck_attr_alloc_init();
lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_attr);
#else
SCTP_BASE_INFO(sctbinfo).ipi_listhead = &SCTP_BASE_INFO(inplisthead);
SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr = lck_grp_attr_alloc_init();
lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
SCTP_BASE_INFO(sctbinfo).ipi_lock_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
SCTP_BASE_INFO(sctbinfo).ipi_lock_attr = lck_attr_alloc_init();
lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
#endif
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
SCTP_BASE_INFO(sctbinfo).ipi_gc = sctp_gc;
in_pcbinfo_attach(&SCTP_BASE_INFO(sctbinfo));
#endif
#endif
@ -6674,17 +6714,6 @@ sctp_pcb_init()
/* Master Lock INIT for info structure */
#if defined(__APPLE__)
/* allocate the lock group attribute for SCTP PCB mutexes */
SCTP_BASE_INFO(mtx_grp_attr) = lck_grp_attr_alloc_init();
lck_grp_attr_setdefault(SCTP_BASE_INFO(mtx_grp_attr));
/* allocate the lock group for SCTP PCB mutexes */
SCTP_BASE_INFO(mtx_grp) = lck_grp_alloc_init("sctppcb",
SCTP_BASE_INFO(mtx_grp_attr));
/* allocate the lock attribute for SCTP PCB mutexes */
SCTP_BASE_INFO(mtx_attr) = lck_attr_alloc_init();
lck_attr_setdefault(SCTP_BASE_INFO(mtx_attr));
#endif /* __APPLE__ */
SCTP_INP_INFO_LOCK_INIT();
SCTP_STATLOG_INIT_LOCK();
@ -6722,7 +6751,6 @@ sctp_pcb_init()
for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
}
#if defined(SCTP_PROCESS_LEVEL_LOCKS)
#if defined(__Userspace_os_Windows)
InitializeConditionVariable(&sctp_it_ctl.iterator_wakeup);
@ -6777,37 +6805,9 @@ sctp_pcb_finish(void)
struct sctp_tagblock *twait_block, *prev_twait_block;
struct sctp_laddr *wi, *nwi;
int i;
#if defined(__FreeBSD__)
/* Free BSD the it thread never exits
* but we do clean up. The only way
* freebsd reaches here if we have VRF's
* but we still add the ifdef to make it
* compile on old versions.
*/
{
struct sctp_iterator *it, *nit;
SCTP_IPI_ITERATOR_WQ_LOCK();
TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
if (it->vn != curvnet) {
continue;
}
TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
if (it->function_atend != NULL) {
(*it->function_atend) (it->pointer, it->val);
}
SCTP_FREE(it,SCTP_M_ITER);
}
SCTP_IPI_ITERATOR_WQ_UNLOCK();
SCTP_ITERATOR_LOCK();
if ((sctp_it_ctl.cur_it) &&
(sctp_it_ctl.cur_it->vn == curvnet)) {
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
}
SCTP_ITERATOR_UNLOCK();
}
#else
struct sctp_iterator *it, *nit;
#if !defined(__FreeBSD__)
/* Notify the iterator to exit. */
SCTP_IPI_ITERATOR_WQ_LOCK();
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_MUST_EXIT;
@ -6815,6 +6815,9 @@ sctp_pcb_finish(void)
SCTP_IPI_ITERATOR_WQ_UNLOCK();
#endif
#if defined(__APPLE__)
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
in_pcbinfo_detach(&SCTP_BASE_INFO(sctbinfo));
#endif
SCTP_IPI_ITERATOR_WQ_LOCK();
do {
msleep(&sctp_it_ctl.iterator_flags,
@ -6823,8 +6826,6 @@ sctp_pcb_finish(void)
} while ((sctp_it_ctl.iterator_flags & SCTP_ITERATOR_EXITED) == 0);
thread_deallocate(sctp_it_ctl.thread_proc);
SCTP_IPI_ITERATOR_WQ_UNLOCK();
SCTP_IPI_ITERATOR_WQ_DESTROY();
SCTP_ITERATOR_LOCK_DESTROY();
#endif
#if defined(__Windows__)
if (sctp_it_ctl.iterator_thread_obj != NULL) {
@ -6839,7 +6840,56 @@ sctp_pcb_finish(void)
ObDereferenceObject(sctp_it_ctl.iterator_thread_obj);
}
#endif
#if defined(__Userspace__)
if (sctp_it_ctl.thread_proc) {
#if defined(__Userspace_os_Windows)
WaitForSingleObject(sctp_it_ctl.thread_proc, INFINITE);
CloseHandle(sctp_it_ctl.thread_proc);
sctp_it_ctl.thread_proc = NULL;
#else
pthread_join(sctp_it_ctl.thread_proc, NULL);
sctp_it_ctl.thread_proc = 0;
#endif
}
#endif
#if defined(SCTP_PROCESS_LEVEL_LOCKS)
#if defined(__Userspace_os_Windows)
DeleteConditionVariable(&sctp_it_ctl.iterator_wakeup);
#else
pthread_cond_destroy(&sctp_it_ctl.iterator_wakeup);
#endif
#endif
/* In FreeBSD the iterator thread never exits
* but we do clean up.
* The only way FreeBSD reaches here is if we have VRF's
* but we still add the ifdef to make it compile on old versions.
*/
SCTP_IPI_ITERATOR_WQ_LOCK();
TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
if (it->vn != curvnet) {
continue;
}
#endif
TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
if (it->function_atend != NULL) {
(*it->function_atend) (it->pointer, it->val);
}
SCTP_FREE(it,SCTP_M_ITER);
}
SCTP_IPI_ITERATOR_WQ_UNLOCK();
#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
SCTP_ITERATOR_LOCK();
if ((sctp_it_ctl.cur_it) &&
(sctp_it_ctl.cur_it->vn == curvnet)) {
sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
}
SCTP_ITERATOR_UNLOCK();
#endif
#if !defined(__FreeBSD__)
SCTP_IPI_ITERATOR_WQ_DESTROY();
SCTP_ITERATOR_LOCK_DESTROY();
#endif
SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
SCTP_WQ_ADDR_LOCK();
LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
@ -6877,7 +6927,9 @@ sctp_pcb_finish(void)
SCTP_HASH_FREE(SCTP_BASE_INFO(vrf_ifn_hash), SCTP_BASE_INFO(vrf_ifn_hashmark));
#if defined(__Userspace__) && !defined(__Userspace_os_Windows)
/* free memory allocated by getifaddrs call */
#if defined(INET) || defined(INET6)
freeifaddrs(g_interfaces);
#endif
#endif
/* free the TIMEWAIT list elements malloc'd in the function
@ -6909,16 +6961,20 @@ sctp_pcb_finish(void)
SCTP_IPI_COUNT_DESTROY();
#endif
SCTP_STATLOG_DESTROY();
#if !defined(__Userspace__)
SCTP_INP_INFO_LOCK_DESTROY();
#endif
SCTP_WQ_ADDR_DESTROY();
#if defined(__APPLE__)
lck_grp_attr_free(SCTP_BASE_INFO(mtx_grp_attr));
lck_grp_free(SCTP_BASE_INFO(mtx_grp));
lck_attr_free(SCTP_BASE_INFO(mtx_attr));
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
lck_grp_free(SCTP_BASE_INFO(sctbinfo).mtx_grp);
lck_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_attr);
#else
lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
lck_grp_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp);
lck_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
#endif
#endif
#if defined(__Userspace__)
SCTP_TIMERQ_LOCK_DESTROY();
@ -7656,30 +7712,28 @@ skip_vtag_check:
chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
/* Now what about timed wait ? */
if (!LIST_EMPTY(chain)) {
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
/*
* Block(s) are present, lets see if we have this tag in the
* list
*/
LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if (twait_block->vtag_block[i].v_tag == 0) {
/* not used */
continue;
} else if ((long)twait_block->vtag_block[i].tv_sec_at_expire <
now->tv_sec) {
/* Audit expires this guy */
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
twait_block->vtag_block[i].lport = 0;
twait_block->vtag_block[i].rport = 0;
} else if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
/* Bad tag, sorry :< */
SCTP_INP_INFO_RUNLOCK();
return (0);
}
for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
if (twait_block->vtag_block[i].v_tag == 0) {
/* not used */
continue;
} else if ((long)twait_block->vtag_block[i].tv_sec_at_expire <
now->tv_sec) {
/* Audit expires this guy */
twait_block->vtag_block[i].tv_sec_at_expire = 0;
twait_block->vtag_block[i].v_tag = 0;
twait_block->vtag_block[i].lport = 0;
twait_block->vtag_block[i].rport = 0;
} else if ((twait_block->vtag_block[i].v_tag == tag) &&
(twait_block->vtag_block[i].lport == lport) &&
(twait_block->vtag_block[i].rport == rport)) {
/* Bad tag, sorry :< */
SCTP_INP_INFO_RUNLOCK();
return (0);
}
}
}

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 246687 2013-02-11 21:02:49Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 254248 2013-08-12 13:52:15Z tuexen $");
#endif
#ifndef _NETINET_SCTP_PCB_H_
@ -189,6 +189,7 @@ struct sctp_epinfo {
#if defined(__APPLE__)
struct inpcbhead inplisthead;
struct inpcbinfo sctbinfo;
#endif
/* ep zone info */
sctp_zone_t ipi_zone_ep;
@ -223,20 +224,12 @@ struct sctp_epinfo {
userland_mutex_t wq_addr_mtx;
#elif defined(__APPLE__)
#ifdef _KERN_LOCKS_H_
lck_grp_attr_t *mtx_grp_attr;
lck_grp_t *mtx_grp;
lck_attr_t *mtx_attr;
lck_rw_t *ipi_ep_mtx;
lck_mtx_t *ipi_addr_mtx;
lck_mtx_t *ipi_count_mtx;
lck_mtx_t *ipi_pktlog_mtx;
lck_mtx_t *logging_mtx;
lck_mtx_t *wq_addr_mtx;
#else
void *mtx_grp_attr;
void *mtx_grp;
void *mtx_attr;
void *ipi_ep_mtx;
void *ipi_count_mtx;
void *logging_mtx;
#endif /* _KERN_LOCKS_H_ */
@ -469,8 +462,8 @@ struct sctp_inpcb {
/* back pointer to our socket */
struct socket *sctp_socket;
uint64_t sctp_features; /* Feature flags */
uint32_t sctp_flags; /* INP state flag set */
uint32_t sctp_features; /* Feature flags */
uint32_t sctp_mobility_features; /* Mobility Feature flags */
struct sctp_pcb sctp_ep;/* SCTP ep data */
/* head of the hash of all associations */

View File

@ -126,6 +126,8 @@
#define SCTP_INP_INFO_LOCK_INIT() \
InitializeCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_LOCK_DESTROY() \
DeleteCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_RLOCK() \
EnterCriticalSection(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_TRYLOCK() \
@ -275,6 +277,8 @@
#define SCTP_INP_INFO_LOCK_INIT() \
(void)pthread_mutex_init(&SCTP_BASE_INFO(ipi_ep_mtx), NULL)
#define SCTP_INP_INFO_LOCK_DESTROY() \
(void)pthread_mutex_destroy(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_RLOCK() \
(void)pthread_mutex_lock(&SCTP_BASE_INFO(ipi_ep_mtx))
#define SCTP_INP_INFO_TRYLOCK() \

View File

@ -1,7 +1,8 @@
/*-
* Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
* Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
* Copyright (c) 2008-2013, by Michael Tuexen. All rights reserved.
* Copyright (c) 2013, by Lally Singh. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@ -30,26 +31,84 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#endif
#include <netinet/sctp_sha1.h>
#if !defined(__Userspace_os_Windows)
#include <sys/param.h>
#if !defined(__Windows__)
#if defined(SCTP_USE_NSS_SHA1)
/* A SHA-1 Digest is 160 bits, or 20 bytes */
#define SHA_DIGEST_LENGTH (20)
void
sctp_sha1_init(struct sctp_sha1_context *ctx)
{
ctx->pk11_ctx = PK11_CreateDigestContext(SEC_OID_SHA1);
PK11_DigestBegin(ctx->pk11_ctx);
}
void
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
{
PK11_DigestOp(ctx->pk11_ctx, ptr, siz);
}
void
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
{
unsigned int output_len = 0;
PK11_DigestFinal(ctx->pk11_ctx, digest, &output_len, SHA_DIGEST_LENGTH);
PK11_DestroyContext(ctx->pk11_ctx, PR_TRUE);
}
#elif defined(SCTP_USE_OPENSSL_SHA1)
void
sctp_sha1_init(struct sctp_sha1_context *ctx)
{
SHA1_Init(&ctx->sha_ctx);
}
void
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
{
SHA1_Update(&ctx->sha_ctx, ptr, (unsigned long)siz);
}
void
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
{
SHA1_Final(digest, &ctx->sha_ctx);
}
#else
#include <string.h>
#if defined(__Userspace_os_Windows)
#include <winsock2.h>
#elif !defined(__Windows__)
#include <arpa/inet.h>
#endif
#else
#include <winsock2.h>
#endif
#if !defined(__Userspace__)
#include <sys/systm.h>
#endif
#include <string.h>
#define F1(B,C,D) (((B & C) | ((~B) & D))) /* 0 <= t <= 19 */
#define F2(B,C,D) (B ^ C ^ D) /* 20 <= t <= 39 */
#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */
#define F4(B,C,D) (B ^ C ^ D) /* 600 <= t <= 79 */
/* circular shift */
#define CSHIFT(A,B) ((B << A) | (B >> (32-A)))
#define K1 0x5a827999 /* 0 <= t <= 19 */
#define K2 0x6ed9eba1 /* 20 <= t <= 39 */
#define K3 0x8f1bbcdc /* 40 <= t <= 59 */
#define K4 0xca62c1d6 /* 60 <= t <= 79 */
#define H0INIT 0x67452301
#define H1INIT 0xefcdab89
#define H2INIT 0x98badcfe
#define H3INIT 0x10325476
#define H4INIT 0xc3d2e1f0
void
SHA1_Init(struct sha1_context *ctx)
sctp_sha1_init(struct sctp_sha1_context *ctx)
{
/* Init the SHA-1 context structure */
ctx->A = 0;
@ -69,7 +128,7 @@ SHA1_Init(struct sha1_context *ctx)
}
static void
sha1_process_a_block(struct sha1_context *ctx, unsigned int *block)
sctp_sha1_process_a_block(struct sctp_sha1_context *ctx, unsigned int *block)
{
int i;
@ -133,11 +192,10 @@ sha1_process_a_block(struct sha1_context *ctx, unsigned int *block)
ctx->H4 = (ctx->H4) + (ctx->E);
}
void
SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz)
sctp_sha1_update(struct sctp_sha1_context *ctx, const unsigned char *ptr, unsigned int siz)
{
int number_left, left_to_fill;
unsigned int number_left, left_to_fill;
number_left = siz;
while (number_left > 0) {
@ -154,7 +212,7 @@ SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz)
/* block is now full, process it */
memcpy(&ctx->sha_block[ctx->how_many_in_block],
ptr, left_to_fill);
sha1_process_a_block(ctx,
sctp_sha1_process_a_block(ctx,
(unsigned int *)ctx->sha_block);
number_left -= left_to_fill;
ctx->running_total += left_to_fill;
@ -165,7 +223,7 @@ SHA1_Update(struct sha1_context *ctx, const unsigned char *ptr, int siz)
}
void
SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
sctp_sha1_final(unsigned char *digest, struct sctp_sha1_context *ctx)
{
/*
* if any left in block fill with padding and process. Then transfer
@ -191,7 +249,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
left_to_fill = sizeof(ctx->sha_block) - ctx->how_many_in_block;
if (left_to_fill == 0) {
/* Should not really happen but I am paranoid */
sha1_process_a_block(ctx,
sctp_sha1_process_a_block(ctx,
(unsigned int *)ctx->sha_block);
/* init last block, a bit different than the rest */
ctx->sha_block[0] = '\x80';
@ -200,7 +258,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
}
} else if (left_to_fill == 1) {
ctx->sha_block[ctx->how_many_in_block] = '\x80';
sha1_process_a_block(ctx,
sctp_sha1_process_a_block(ctx,
(unsigned int *)ctx->sha_block);
/* init last block */
memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
@ -211,7 +269,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
i++) {
ctx->sha_block[i] = 0x0;
}
sha1_process_a_block(ctx,
sctp_sha1_process_a_block(ctx,
(unsigned int *)ctx->sha_block);
/* init last block */
memset(ctx->sha_block, 0, sizeof(ctx->sha_block));
@ -220,7 +278,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
ctx->running_total *= 8;
ptr = (unsigned int *)&ctx->sha_block[60];
*ptr = htonl(ctx->running_total);
sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
} else {
/*
* easy case, we just pad this message to size - end with 0
@ -238,7 +296,7 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
ctx->running_total *= 8;
ptr = (unsigned int *)&ctx->sha_block[60];
*ptr = htonl(ctx->running_total);
sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
sctp_sha1_process_a_block(ctx, (unsigned int *)ctx->sha_block);
}
/* transfer the digest back to the user */
digest[3] = (ctx->H0 & 0xff);
@ -266,3 +324,5 @@ SHA1_Final(unsigned char *digest, struct sha1_context *ctx)
digest[17] = ((ctx->H4 >> 16) & 0xff);
digest[16] = ((ctx->H4 >> 24) & 0xff);
}
#endif

View File

@ -36,12 +36,31 @@ __FBSDID("$FreeBSD$");
#endif
#ifndef __SCTP_SLA1_h__
#define __SCTP_SLA1_h__
#ifndef __NETINET_SCTP_SHA1_H__
#define __NETINET_SCTP_SHA1_H__
#include <sys/types.h>
#if defined(SCTP_USE_NSS_SHA1)
#if defined(__Userspace_os_Darwin)
/* The NSS sources require __APPLE__ to be defined.
* XXX: Remove this ugly hack once the platform defines have been cleaned up.
*/
#define __APPLE__
#endif
#include <pk11pub.h>
#if defined(__Userspace_os_Darwin)
#undef __APPLE__
#endif
#elif defined(SCTP_USE_OPENSSL_SHA1)
#include <openssl/sha.h>
#endif
struct sha1_context {
struct sctp_sha1_context {
#if defined(SCTP_USE_NSS_SHA1)
struct PK11Context *pk11_ctx;
#elif defined(SCTP_USE_OPENSSL_SHA1)
SHA_CTX sha_ctx;
#else
unsigned int A;
unsigned int B;
unsigned int C;
@ -59,28 +78,8 @@ struct sha1_context {
/* collected so far */
int how_many_in_block;
unsigned int running_total;
#endif
};
typedef struct sha1_context SHA1_CTX;
#define F1(B,C,D) (((B & C) | ((~B) & D))) /* 0 <= t <= 19 */
#define F2(B,C,D) (B ^ C ^ D) /* 20 <= t <= 39 */
#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */
#define F4(B,C,D) (B ^ C ^ D) /* 600 <= t <= 79 */
/* circular shift */
#define CSHIFT(A,B) ((B << A) | (B >> (32-A)))
#define K1 0x5a827999 /* 0 <= t <= 19 */
#define K2 0x6ed9eba1 /* 20 <= t <= 39 */
#define K3 0x8f1bbcdc /* 40 <= t <= 59 */
#define K4 0xca62c1d6 /* 60 <= t <= 79 */
#define H0INIT 0x67452301
#define H1INIT 0xefcdab89
#define H2INIT 0x98badcfe
#define H3INIT 0x10325476
#define H4INIT 0xc3d2e1f0
#if (defined(__APPLE__) && defined(KERNEL))
#ifndef _KERNEL
@ -90,9 +89,9 @@ typedef struct sha1_context SHA1_CTX;
#if defined(_KERNEL) || defined(__Userspace__)
void SHA1_Init(struct sha1_context *);
void SHA1_Update(struct sha1_context *, const unsigned char *, int);
void SHA1_Final(unsigned char *, struct sha1_context *);
void sctp_sha1_init(struct sctp_sha1_context *);
void sctp_sha1_update(struct sctp_sha1_context *, const unsigned char *, unsigned int);
void sctp_sha1_final(unsigned char *, struct sctp_sha1_context *);
#endif /* _KERNEL */
#endif
#endif

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 246595 2013-02-09 17:26:14Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 255190 2013-09-03 19:31:59Z tuexen $");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
@ -236,6 +236,9 @@ struct sctp_net_route {
#endif
#endif
#if defined(__APPLE__)
#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
struct ifaddr *ro_srcia;
#endif
#if !defined(APPLE_LEOPARD)
uint32_t ro_flags;
#endif
@ -493,7 +496,6 @@ struct sctp_tmit_chunk {
uint8_t do_rtt;
uint8_t book_size_scale;
uint8_t no_fr_allowed;
uint8_t pr_sctp_on;
uint8_t copy_by_ref;
uint8_t window_probe;
};
@ -568,7 +570,6 @@ struct sctp_stream_queue_pending {
uint8_t holds_key_ref;
uint8_t msg_is_complete;
uint8_t some_taken;
uint8_t pr_sctp_on;
uint8_t sender_all_done;
uint8_t put_last_out;
uint8_t discard_rest;
@ -1252,7 +1253,7 @@ struct sctp_association {
/* JRS 5/21/07 - CMT PF variable */
uint8_t sctp_cmt_pf;
uint8_t use_precise_time;
uint32_t sctp_features;
uint64_t sctp_features;
uint16_t port; /* remote UDP encapsulation port */
/*
* The mapping array is used to track out of order sequences above

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 246595 2013-02-09 17:26:14Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 254672 2013-08-22 20:29:57Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -93,6 +93,7 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_path_rtx_max_default) = SCTPCTL_PATH_RTX_MAX_DEFAULT;
SCTP_BASE_SYSCTL(sctp_path_pf_threshold) = SCTPCTL_PATH_PF_THRESHOLD_DEFAULT;
SCTP_BASE_SYSCTL(sctp_add_more_threshold) = SCTPCTL_ADD_MORE_ON_OUTPUT_DEFAULT;
SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default) = SCTPCTL_INCOMING_STREAMS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default) = SCTPCTL_OUTGOING_STREAMS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_cmt_on_off) = SCTPCTL_CMT_ON_OFF_DEFAULT;
/* EY */
@ -491,7 +492,11 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
xinpcb.last = 0;
xinpcb.local_port = ntohs(inp->sctp_lport);
xinpcb.flags = inp->sctp_flags;
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
xinpcb.features = (uint32_t)inp->sctp_features;
#else
xinpcb.features = inp->sctp_features;
#endif
xinpcb.total_sends = inp->total_sends;
xinpcb.total_recvs = inp->total_recvs;
xinpcb.total_nospaces = inp->total_nospaces;
@ -788,6 +793,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), SCTPCTL_PATH_RTX_MAX_MIN, SCTPCTL_PATH_RTX_MAX_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_path_pf_threshold), SCTPCTL_PATH_PF_THRESHOLD_MIN, SCTPCTL_PATH_PF_THRESHOLD_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_add_more_threshold), SCTPCTL_ADD_MORE_ON_OUTPUT_MIN, SCTPCTL_ADD_MORE_ON_OUTPUT_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), SCTPCTL_INCOMING_STREAMS_MIN, SCTPCTL_INCOMING_STREAMS_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), SCTPCTL_OUTGOING_STREAMS_MIN, SCTPCTL_OUTGOING_STREAMS_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_cmt_on_off), SCTPCTL_CMT_ON_OFF_MIN, SCTPCTL_CMT_ON_OFF_MAX);
/* EY */
@ -1180,6 +1186,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, add_more_on_output, CTLTYPE_UINT|CTLF
&SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sysctl_sctp_check, "IU",
SCTPCTL_ADD_MORE_ON_OUTPUT_DESC);
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, incoming_streams, CTLTYPE_UINT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sysctl_sctp_check, "IU",
SCTPCTL_INCOMING_STREAMS_DESC);
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, outgoing_streams, CTLTYPE_UINT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sysctl_sctp_check, "IU",
SCTPCTL_OUTGOING_STREAMS_DESC);
@ -1515,6 +1525,10 @@ void sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sysctl_sctp_check,
SCTPCTL_ADD_MORE_ON_OUTPUT_DESC);
sysctl_add_oid(&sysctl_oid_top, "incoming_streams", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sysctl_sctp_check,
SCTPCTL_INCOMING_STREAMS_DESC);
sysctl_add_oid(&sysctl_oid_top, "outgoing_streams", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sysctl_sctp_check,
SCTPCTL_OUTGOING_STREAMS_DESC);

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 237565 2012-06-25 17:15:09Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 252779 2013-07-05 10:08:49Z tuexen $");
#endif
#ifndef _NETINET_SCTP_SYSCTL_H_
@ -79,6 +79,7 @@ struct sctp_sysctl {
uint32_t sctp_path_rtx_max_default;
uint32_t sctp_path_pf_threshold;
uint32_t sctp_add_more_threshold;
uint32_t sctp_nr_incoming_streams_default;
uint32_t sctp_nr_outgoing_streams_default;
uint32_t sctp_cmt_on_off;
uint32_t sctp_cmt_use_dac;
@ -339,6 +340,12 @@ struct sctp_sysctl {
#define SCTPCTL_ADD_MORE_ON_OUTPUT_MAX 0xFFFFFFFF
#define SCTPCTL_ADD_MORE_ON_OUTPUT_DEFAULT SCTP_DEFAULT_ADD_MORE
/* incoming_streams: Default number of incoming streams */
#define SCTPCTL_INCOMING_STREAMS_DESC "Default number of incoming streams"
#define SCTPCTL_INCOMING_STREAMS_MIN 1
#define SCTPCTL_INCOMING_STREAMS_MAX 65535
#define SCTPCTL_INCOMING_STREAMS_DEFAULT SCTP_ISTREAM_INITIAL
/* outgoing_streams: Default number of outgoing streams */
#define SCTPCTL_OUTGOING_STREAMS_DESC "Default number of outgoing streams"
#define SCTPCTL_OUTGOING_STREAMS_MIN 1

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 246588 2013-02-09 08:27:08Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 257359 2013-10-29 20:04:50Z tuexen $");
#endif
#define _IP_VHL
@ -442,7 +442,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
}
}
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
if (chk->pr_sctp_on) {
if (PR_SCTP_ENABLED(chk->flags)) {
if (asoc->pr_sctp_cnt != 0)
asoc->pr_sctp_cnt--;
}
@ -551,7 +551,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
TAILQ_FOREACH_SAFE(chk, &stcb->asoc.sent_queue, sctp_next, nchk) {
if (SCTP_TSN_GE(stcb->asoc.last_acked_seq, chk->rec.data.TSN_seq)) {
/* Strange case our list got out of order? */
SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x",
SCTP_PRINTF("Our list is out of order? last_acked:%x chk:%x\n",
(unsigned int)stcb->asoc.last_acked_seq, (unsigned int)chk->rec.data.TSN_seq);
recovery_cnt++;
#ifdef INVARIANTS

View File

@ -96,8 +96,11 @@ void sctp_audit_retranmission_queue(struct sctp_association *);
void sctp_iterator_timer(struct sctp_iterator *it);
#if defined(__APPLE__)
void sctp_slowtimo();
#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
void sctp_slowtimo(void);
#else
void sctp_gc(struct inpcbinfo *);
#endif
#endif
#endif

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 242327 2012-10-29 20:47:32Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 255160 2013-09-02 22:48:41Z tuexen $");
#endif
#ifndef _NETINET_SCTP_UIO_H_
@ -691,10 +691,6 @@ struct sctp_hmacalgo {
#define SCTP_AUTH_HMAC_ID_RSVD 0x0000
#define SCTP_AUTH_HMAC_ID_SHA1 0x0001 /* default, mandatory */
#define SCTP_AUTH_HMAC_ID_SHA256 0x0003
#define SCTP_AUTH_HMAC_ID_SHA224 0x0004
#define SCTP_AUTH_HMAC_ID_SHA384 0x0005
#define SCTP_AUTH_HMAC_ID_SHA512 0x0006
/* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */
struct sctp_authkeyid {
@ -1174,7 +1170,11 @@ union sctp_sockstore {
struct xsctp_inpcb {
uint32_t last;
uint32_t flags;
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
uint32_t features;
#else
uint64_t features;
#endif
uint32_t total_sends;
uint32_t total_recvs;
uint32_t total_nospaces;
@ -1185,7 +1185,11 @@ struct xsctp_inpcb {
#if defined(__Windows__)
uint16_t padding;
#endif
#if defined(__FreeBSD__) && __FreeBSD_version < 1000048
uint32_t extra_padding[32]; /* future */
#else
uint32_t extra_padding[31]; /* future */
#endif
};
struct xsctp_tcb {
@ -1328,7 +1332,7 @@ sctp_sorecvmsg(struct socket *so,
#if !(defined(_KERNEL)) && !(defined(__Userspace__))
__BEGIN_DECLS
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp_peeloff __P((int, sctp_assoc_t));
int sctp_bindx __P((int, struct sockaddr *, int, int));
int sctp_connectx __P((int, const struct sockaddr *, int, sctp_assoc_t *));

View File

@ -97,17 +97,21 @@ getwintimeofday(struct timeval *tv)
int
Win_getifaddrs(struct ifaddrs** interfaces)
{
#if defined(INET) || defined(INET6)
DWORD Err, AdapterAddrsSize;
int count;
PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt;
struct ifaddrs *ifa;
#endif
#if defined(INET)
struct sockaddr_in *addr;
#endif
#if defined(INET6)
struct sockaddr_in6 *addr6;
#endif
#if defined(INET) || defined(INET6)
count = 0;
#endif
#if defined(INET)
AdapterAddrsSize = 0;
if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) {

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 246687 2013-02-11 21:02:49Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 259943 2013-12-27 13:07:00Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -76,6 +76,8 @@ void
sctp_init(uint16_t port,
int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*debug_printf)(const char *format, ...))
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
sctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED)
#else
sctp_init(void)
#endif
@ -84,16 +86,22 @@ sctp_init(void)
u_long sb_max_adj;
#endif
#if defined(__Userspace__)
#if defined(__Userspace_os_Windows)
#if defined(INET) || defined(INET6)
WSADATA wsaData;
int Ret;
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData))!=0) {
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
SCTP_PRINTF("WSAStartup failed\n");
exit (-1);
}
#endif
InitializeConditionVariable(&accept_cond);
InitializeCriticalSection(&accept_mtx);
#else
pthread_cond_init(&accept_cond, NULL);
pthread_mutex_init(&accept_mtx, NULL);
#endif
#endif
/* Initialize and modify the sysctled variables */
sctp_init_sysctls();
@ -171,8 +179,7 @@ sctp_init(void)
#if defined(__APPLE__)
SCTP_BASE_VAR(sctp_main_timer_ticks) = 0;
sctp_start_main_timer();
sctp_address_monitor_start();
sctp_over_udp_start();
timeout(sctp_delayed_startup, NULL, 1);
#endif
}
@ -180,6 +187,7 @@ void
sctp_finish(void)
{
#if defined(__APPLE__)
untimeout(sctp_delayed_startup, NULL);
sctp_over_udp_stop();
sctp_address_monitor_stop();
sctp_stop_main_timer();
@ -199,6 +207,7 @@ sctp_finish(void)
if (SCTP_BASE_VAR(userspace_rawsctp) != -1) {
#if defined(__Userspace_os_Windows)
WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw), INFINITE);
CloseHandle(SCTP_BASE_VAR(recvthreadraw));
#else
pthread_join(SCTP_BASE_VAR(recvthreadraw), NULL);
#endif
@ -206,6 +215,7 @@ sctp_finish(void)
if (SCTP_BASE_VAR(userspace_udpsctp) != -1) {
#if defined(__Userspace_os_Windows)
WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp), INFINITE);
CloseHandle(SCTP_BASE_VAR(recvthreadudp));
#else
pthread_join(SCTP_BASE_VAR(recvthreadudp), NULL);
#endif
@ -215,6 +225,7 @@ sctp_finish(void)
if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) {
#if defined(__Userspace_os_Windows)
WaitForSingleObject(SCTP_BASE_VAR(recvthreadraw6), INFINITE);
CloseHandle(SCTP_BASE_VAR(recvthreadraw6));
#else
pthread_join(SCTP_BASE_VAR(recvthreadraw6), NULL);
#endif
@ -222,6 +233,7 @@ sctp_finish(void)
if (SCTP_BASE_VAR(userspace_udpsctp6) != -1) {
#if defined(__Userspace_os_Windows)
WaitForSingleObject(SCTP_BASE_VAR(recvthreadudp6), INFINITE);
CloseHandle(SCTP_BASE_VAR(recvthreadudp6));
#else
pthread_join(SCTP_BASE_VAR(recvthreadudp6), NULL);
#endif
@ -230,13 +242,26 @@ sctp_finish(void)
SCTP_BASE_VAR(timer_thread_should_exit) = 1;
#if defined(__Userspace_os_Windows)
WaitForSingleObject(SCTP_BASE_VAR(timer_thread), INFINITE);
CloseHandle(SCTP_BASE_VAR(timer_thread));
#else
pthread_join(SCTP_BASE_VAR(timer_thread), NULL);
#endif
#endif
sctp_pcb_finish();
#if defined(__Userspace__)
#if defined(__Userspace_os_Windows)
DeleteConditionVariable(&accept_cond);
DeleteCriticalSection(&accept_mtx);
#else
pthread_cond_destroy(&accept_cond);
pthread_mutex_destroy(&accept_mtx);
#endif
#endif
#if defined(__Windows__)
sctp_finish_sysctls();
#if defined(INET) || defined(INET6)
WSACleanup();
#endif
#endif
}
@ -412,8 +437,10 @@ sctp_notify(struct sctp_inpcb *inp,
(icmph->icmp_code == ICMP_UNREACH_ISOLATED) ||
(icmph->icmp_code == ICMP_UNREACH_NET_PROHIB) ||
(icmph->icmp_code == ICMP_UNREACH_HOST_PROHIB) ||
#ifdef __Panda__
#if defined(__Panda__)
(icmph->icmp_code == ICMP_UNREACH_ADMIN)) {
#elif defined(__Userspace_os_NetBSD)
(icmph->icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
#else
(icmph->icmp_code == ICMP_UNREACH_FILTER_PROHIB)) {
#endif
@ -1162,11 +1189,11 @@ sctp_disconnect(struct socket *so)
}
#if defined(__Userspace__)
if (((so->so_options & SCTP_SO_LINGER) &&
(so->so_linger == 0)) ||
(so->so_linger == 0)) ||
(so->so_rcv.sb_cc > 0)) {
#else
if (((so->so_options & SO_LINGER) &&
(so->so_linger == 0)) ||
(so->so_linger == 0)) ||
(so->so_rcv.sb_cc > 0)) {
#endif
if (SCTP_GET_STATE(asoc) !=
@ -1558,9 +1585,14 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
{
struct sctp_ifn *sctp_ifn;
struct sctp_ifa *sctp_ifa;
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
size_t actual;
int ipv4_addr_legal, ipv6_addr_legal;
int loopback_scope;
#if defined(INET)
int ipv4_local_scope, ipv4_addr_legal;
#endif
#if defined(INET6)
int local_scope, site_scope, ipv6_addr_legal;
#endif
#if defined(__Userspace__)
int conn_addr_legal;
#endif
@ -1573,42 +1605,62 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
if (stcb) {
/* Turn on all the appropriate scope */
loopback_scope = stcb->asoc.scope.loopback_scope;
#if defined(INET)
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
#endif
#if defined(INET6)
local_scope = stcb->asoc.scope.local_scope;
site_scope = stcb->asoc.scope.site_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
#endif
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif
} else {
/* Use generic values for endpoints. */
loopback_scope = 1;
#if defined(INET)
ipv4_local_scope = 1;
#endif
#if defined(INET6)
local_scope = 1;
site_scope = 1;
#endif
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
#if defined(INET6)
ipv6_addr_legal = 1;
#endif
#if defined(INET)
if (SCTP_IPV6_V6ONLY(inp)) {
ipv4_addr_legal = 0;
} else {
ipv4_addr_legal = 1;
}
#endif
#if defined(__Userspace__)
conn_addr_legal = 0;
#endif
} else {
#if defined(INET6)
ipv6_addr_legal = 0;
#endif
#if defined(__Userspace__)
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
conn_addr_legal = 1;
#if defined(INET)
ipv4_addr_legal = 0;
#endif
} else {
conn_addr_legal = 0;
#if defined(INET)
ipv4_addr_legal = 1;
#endif
}
#else
#if defined(INET)
ipv4_addr_legal = 1;
#endif
#endif
}
}
@ -3391,7 +3443,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
if (stcb) {
/* simply copy out the sockaddr_storage... */
int len;
size_t len;
len = *optsize;
#ifdef HAVE_SA_LEN
@ -3954,7 +4006,7 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
}
if (error == 0) {
*optsize = sizeof(struct sctp_paddrparams);
*optsize = sizeof(struct sctp_udpencaps);
}
break;
}
@ -4726,7 +4778,6 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
sctp_hmaclist_t *hmaclist;
uint16_t hmacid;
uint32_t i;
size_t found;
SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize);
if (optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) {
@ -4751,14 +4802,14 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
goto sctp_set_hmac_done;
}
}
found = 0;
for (i = 0; i < hmaclist->num_algo; i++) {
if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) {
/* already in list */
found = 1;
break;
}
}
if (!found) {
if (i == hmaclist->num_algo) {
/* not found in list */
sctp_free_hmaclist(hmaclist);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
@ -5592,11 +5643,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10);
}
net->dest_state |= SCTP_ADDR_NO_PMTUD;
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
net->mtu = paddrp->spp_pathmtu + ovh;
if (net->mtu < stcb->asoc.smallest_mtu) {
sctp_pathmtu_adjustment(stcb, net->mtu);
}
net->mtu = paddrp->spp_pathmtu + ovh;
if (net->mtu < stcb->asoc.smallest_mtu) {
sctp_pathmtu_adjustment(stcb, net->mtu);
}
}
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
@ -5717,11 +5766,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_FROM_SCTP_USRREQ+SCTP_LOC_10);
}
net->dest_state |= SCTP_ADDR_NO_PMTUD;
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
net->mtu = paddrp->spp_pathmtu + ovh;
if (net->mtu < stcb->asoc.smallest_mtu) {
sctp_pathmtu_adjustment(stcb, net->mtu);
}
net->mtu = paddrp->spp_pathmtu + ovh;
if (net->mtu < stcb->asoc.smallest_mtu) {
sctp_pathmtu_adjustment(stcb, net->mtu);
}
}
sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
@ -7754,7 +7801,7 @@ sctp_peeraddr(struct socket *so, struct mbuf *nam)
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
struct pr_usrreqs sctp_usrreqs = {
#if __FreeBSD_version >= 600000
#if defined(__FreeBSD__)
.pru_abort = sctp_abort,
.pru_accept = sctp_accept,
.pru_attach = sctp_attach,
@ -7778,45 +7825,51 @@ struct pr_usrreqs sctp_usrreqs = {
.pru_sockaddr = sctp_ingetaddr,
.pru_sosend = sctp_sosend,
.pru_soreceive = sctp_soreceive
#else
#elif defined(__APPLE__)
.pru_abort = sctp_abort,
.pru_accept = sctp_accept,
.pru_attach = sctp_attach,
.pru_bind = sctp_bind,
.pru_connect = sctp_connect,
.pru_connect2 = pru_connect2_notsupp,
.pru_control = in_control,
.pru_detach = sctp_detach,
.pru_disconnect = sctp_disconnect,
.pru_listen = sctp_listen,
.pru_peeraddr = sctp_peeraddr,
.pru_rcvd = NULL,
.pru_rcvoob = pru_rcvoob_notsupp,
.pru_send = sctp_sendm,
.pru_sense = pru_sense_null,
.pru_shutdown = sctp_shutdown,
.pru_sockaddr = sctp_ingetaddr,
.pru_sosend = sctp_sosend,
.pru_soreceive = sctp_soreceive,
.pru_sopoll = sopoll
#elif defined(__Windows__)
sctp_abort,
sctp_accept,
sctp_attach,
sctp_bind,
sctp_connect,
pru_connect2_notsupp,
#if defined(__Windows__)
NULL,
NULL,
#else
in_control,
sctp_detach,
#endif
sctp_disconnect,
sctp_listen,
sctp_peeraddr,
NULL,
pru_rcvoob_notsupp,
#if defined(__Windows__)
NULL,
#else
sctp_sendm,
#endif
pru_sense_null,
sctp_shutdown,
#if defined(__Windows__)
sctp_flush,
#endif
sctp_ingetaddr,
sctp_sosend,
sctp_soreceive,
#if defined(__Windows__)
sopoll_generic,
NULL,
sctp_close
#else
sopoll
#endif
#endif
};
#elif !defined(__Panda__) && !defined(__Userspace__)

View File

@ -399,7 +399,7 @@ int sctp_detach(struct socket *so);
#endif
int sctp_disconnect(struct socket *so);
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
void sctp_ctlinput __P((int, struct sockaddr *, void *));
int sctp_ctloutput __P((struct socket *, struct sockopt *));
#ifdef INET
@ -427,7 +427,7 @@ void sctp_input(struct mbuf *,...);
void *sctp_ctlinput(int, struct sockaddr *, void *);
int sctp_ctloutput(int, struct socket *, int, int, struct mbuf **);
#endif
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
void sctp_drain __P((void));
#else
void sctp_drain(void);
@ -436,18 +436,18 @@ void sctp_drain(void);
void sctp_init(uint16_t,
int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
void (*)(const char *, ...));
#else
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
void sctp_init __P((void));
#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
void sctp_init(struct protosw *pp, struct domain *dp);
#else
void sctp_init(void);
#endif
#endif
void sctp_finish(void);
#if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__)
int sctp_flush(struct socket *, int);
#endif
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp_shutdown __P((struct socket *));
void sctp_notify __P((struct sctp_inpcb *, struct ip *ip, struct sctphdr *,
struct sockaddr *, struct sctp_tcb *,

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 247412 2013-02-27 19:51:47Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 259943 2013-12-27 13:07:00Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -2721,7 +2721,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) {
notif_len = sizeof(struct sctp_assoc_change);
if (abort != NULL) {
abort_len = htons(abort->ch.chunk_length);
abort_len = ntohs(abort->ch.chunk_length);
} else {
abort_len = 0;
}
@ -2756,7 +2756,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
if (stcb->asoc.peer_supports_prsctp) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
}
if (stcb->asoc.peer_supports_auth) {
if (stcb->asoc.peer_supports_auth) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
}
if (stcb->asoc.peer_supports_asconf) {
@ -2774,17 +2774,17 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
}
SCTP_BUF_LEN(m_notify) = sac->sac_length;
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
0, 0, stcb->asoc.context, 0, 0, 0,
m_notify);
0, 0, stcb->asoc.context, 0, 0, 0,
m_notify);
if (control != NULL) {
control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
control->spec_flags = M_NOTIFICATION;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
so_locked);
control,
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
so_locked);
} else {
sctp_m_freem(m_notify);
}
@ -2807,8 +2807,14 @@ set_error:
stcb->sctp_socket->so_error = ECONNRESET;
}
} else {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
stcb->sctp_socket->so_error = ECONNABORTED;
if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) ||
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ETIMEDOUT);
stcb->sctp_socket->so_error = ETIMEDOUT;
} else {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNABORTED);
stcb->sctp_socket->so_error = ECONNABORTED;
}
}
}
/* Wake ANY sleepers */
@ -2929,10 +2935,10 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD,
SCTP_SO_NOT_LOCKED);
control,
&stcb->sctp_socket->so_rcv, 1,
SCTP_READ_LOCK_NOT_HELD,
SCTP_SO_NOT_LOCKED);
}
@ -3611,7 +3617,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
return;
}
if (chunk != NULL) {
chunk_len = htons(chunk->ch.chunk_length);
chunk_len = ntohs(chunk->ch.chunk_length);
} else {
chunk_len = 0;
}
@ -3684,8 +3690,8 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
sctp_unlock_assert(SCTP_INP_SO(stcb->sctp_ep));
}
#endif
if (stcb && ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) ||
(stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED))) {
if ((stcb->asoc.state & SCTP_STATE_COOKIE_WAIT) ||
(stcb->asoc.state & SCTP_STATE_COOKIE_ECHOED)) {
if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) ||
(notification == SCTP_NOTIFY_INTERFACE_UP) ||
(notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) {
@ -3704,7 +3710,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
}
if (stcb->asoc.peer_supports_auth == 0) {
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
NULL, so_locked);
NULL, so_locked);
}
break;
case SCTP_NOTIFY_ASSOC_DOWN:
@ -3755,7 +3761,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
}
case SCTP_NOTIFY_SPECIAL_SP_FAIL:
sctp_notify_send_failed2(stcb, error,
(struct sctp_stream_queue_pending *)data, so_locked);
(struct sctp_stream_queue_pending *)data, so_locked);
break;
case SCTP_NOTIFY_SENT_DG_FAIL:
sctp_notify_send_failed(stcb, 1, error,
@ -3763,7 +3769,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
break;
case SCTP_NOTIFY_UNSENT_DG_FAIL:
sctp_notify_send_failed(stcb, 0, error,
(struct sctp_tmit_chunk *)data, so_locked);
(struct sctp_tmit_chunk *)data, so_locked);
break;
case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
{
@ -3774,16 +3780,16 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
break;
}
case SCTP_NOTIFY_ASSOC_LOC_ABORTED:
if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) {
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 0, so_locked);
} else {
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 0, so_locked);
}
break;
case SCTP_NOTIFY_ASSOC_REM_ABORTED:
if ((stcb) && (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED))) {
if (((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT) ||
((stcb->asoc.state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED)) {
sctp_notify_assoc_change(SCTP_CANT_STR_ASSOC, stcb, error, data, 1, so_locked);
} else {
sctp_notify_assoc_change(SCTP_COMM_LOST, stcb, error, data, 1, so_locked);
@ -3793,7 +3799,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
if (stcb->asoc.peer_supports_auth == 0) {
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
NULL, so_locked);
NULL, so_locked);
}
break;
case SCTP_NOTIFY_STR_RESET_SEND:
@ -3804,7 +3810,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
break;
case SCTP_NOTIFY_STR_RESET_FAILED_OUT:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
(SCTP_STREAM_RESET_OUTGOING_SSN|SCTP_STREAM_RESET_FAILED));
break;
case SCTP_NOTIFY_STR_RESET_DENIED_OUT:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
@ -3812,7 +3818,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
break;
case SCTP_NOTIFY_STR_RESET_FAILED_IN:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
(SCTP_STREAM_RESET_INCOMING|SCTP_STREAM_RESET_FAILED));
break;
case SCTP_NOTIFY_STR_RESET_DENIED_IN:
sctp_notify_stream_reset(stcb, error, ((uint16_t *) data),
@ -3824,29 +3830,29 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
break;
case SCTP_NOTIFY_ASCONF_DELETE_IP:
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_REMOVED, data,
error);
error);
break;
case SCTP_NOTIFY_ASCONF_SET_PRIMARY:
sctp_notify_peer_addr_change(stcb, SCTP_ADDR_MADE_PRIM, data,
error);
error);
break;
case SCTP_NOTIFY_PEER_SHUTDOWN:
sctp_notify_shutdown_event(stcb);
break;
case SCTP_NOTIFY_AUTH_NEW_KEY:
sctp_notify_authentication(stcb, SCTP_AUTH_NEW_KEY, error,
(uint16_t)(uintptr_t)data,
so_locked);
(uint16_t)(uintptr_t)data,
so_locked);
break;
case SCTP_NOTIFY_AUTH_FREE_KEY:
sctp_notify_authentication(stcb, SCTP_AUTH_FREE_KEY, error,
(uint16_t)(uintptr_t)data,
so_locked);
(uint16_t)(uintptr_t)data,
so_locked);
break;
case SCTP_NOTIFY_NO_PEER_AUTH:
sctp_notify_authentication(stcb, SCTP_AUTH_NO_AUTH, error,
(uint16_t)(uintptr_t)data,
so_locked);
(uint16_t)(uintptr_t)data,
so_locked);
break;
case SCTP_NOTIFY_SENDER_DRY:
sctp_notify_sender_dry_event(stcb, so_locked);
@ -4155,7 +4161,7 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (stcb == NULL) {
/* Got to have a TCB */
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
if (LIST_EMPTY(&inp->sctp_asoc_list)) {
#if defined(__APPLE__)
if (!so_locked) {
SCTP_SOCKET_LOCK(so, 1);
@ -4222,7 +4228,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
/* Generate a TO address for future reference */
if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
if (LIST_EMPTY(&inp->sctp_asoc_list)) {
#if defined(__APPLE__)
SCTP_SOCKET_LOCK(SCTP_INP_SO(inp), 1);
#endif
@ -4737,7 +4743,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
char *buffer;
struct sctp_rcvinfo rcv;
union sctp_sockstore addr;
int flags = 0;
int flags;
if ((buffer = malloc(control->length)) == NULL) {
return;
@ -4770,24 +4776,22 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
addr.sin6 = control->whoFrom->ro._l_addr.sin6;
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
addr.sconn = control->whoFrom->ro._l_addr.sconn;
break;
#endif
default:
addr.sa = control->whoFrom->ro._l_addr.sa;
break;
}
flags = MSG_EOR;
if (control->spec_flags & M_NOTIFICATION) {
flags |= MSG_NOTIFICATION;
}
if (control->spec_flags & M_EOR) {
flags |= MSG_EOR;
}
inp->recv_callback(so, addr, buffer, control->length, rcv, flags, inp->ulp_info);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
sctp_free_remote_addr(control->whoFrom);
control->whoFrom = NULL;
sctp_m_freem(control->data);
control->data = NULL;
control->length = 0;
@ -4950,24 +4954,32 @@ sctp_append_to_readq(struct sctp_inpcb *inp,
* is populated in the outbound sinfo structure from the true cumack
* if the association exists...
*/
control->sinfo_tsn = control->sinfo_cumtsn = ctls_cumack;
#if defined(__Userspace__)
if (inp->recv_callback) {
if (control->end_added == 1) {
uint32_t pd_point, length;
length = control->length;
if (stcb != NULL && stcb->sctp_socket != NULL) {
pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT,
stcb->sctp_ep->partial_delivery_point);
} else {
pd_point = inp->partial_delivery_point;
}
if ((control->end_added == 1) || (length >= pd_point)) {
struct socket *so;
char *buffer;
struct sctp_rcvinfo rcv;
union sctp_sockstore addr;
int flags = 0;
int flags;
if ((buffer = malloc(control->length)) == NULL) {
return (-1);
}
so = inp->sctp_socket;
so = stcb->sctp_socket;
for (m = control->data; m; m = SCTP_BUF_NEXT(m)) {
sctp_sbfree(control, control->stcb, &so->so_rcv, m);
}
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
m_copydata(control->data, 0, control->length, buffer);
memset(&rcv, 0, sizeof(struct sctp_rcvinfo));
rcv.rcv_sid = control->sinfo_stream;
@ -4990,35 +5002,42 @@ sctp_append_to_readq(struct sctp_inpcb *inp,
addr.sin6 = control->whoFrom->ro._l_addr.sin6;
break;
#endif
#if defined(__Userspace__)
case AF_CONN:
addr.sconn = control->whoFrom->ro._l_addr.sconn;
break;
#endif
default:
addr.sa = control->whoFrom->ro._l_addr.sa;
break;
}
flags = 0;
if (control->end_added == 1) {
flags |= MSG_EOR;
}
if (control->spec_flags & M_NOTIFICATION) {
flags |= MSG_NOTIFICATION;
}
if (control->spec_flags & M_EOR) {
flags |= MSG_EOR;
}
inp->recv_callback(so, addr, buffer, control->length, rcv, flags, inp->ulp_info);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
sctp_m_freem(control->data);
control->data = NULL;
control->tail_mbuf = NULL;
control->length = 0;
sctp_free_a_readq(stcb, control);
if (control->end_added) {
sctp_free_remote_addr(control->whoFrom);
control->whoFrom = NULL;
sctp_free_a_readq(stcb, control);
} else {
control->some_taken = 1;
}
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
inp->recv_callback(so, addr, buffer, length, rcv, flags, inp->ulp_info);
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
if (inp)
SCTP_INP_READ_UNLOCK(inp);
return (0);
}
#endif
control->sinfo_tsn = control->sinfo_cumtsn = ctls_cumack;
if (inp) {
SCTP_INP_READ_UNLOCK(inp);
}
@ -5272,7 +5291,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
chk->rec.data.TSN_seq = stcb->asoc.sending_seq++;
#endif
stcb->asoc.pr_sctp_cnt++;
chk->pr_sctp_on = 1;
TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
stcb->asoc.sent_queue_cnt++;
stcb->asoc.pr_sctp_cnt++;
@ -5431,10 +5449,10 @@ sctp_get_ifa_hash_val(struct sockaddr *addr)
case AF_CONN:
{
struct sockaddr_conn *sconn;
uint64_t temp;
uintptr_t temp;
sconn = (struct sockaddr_conn *)addr;
temp = (uint64_t)sconn->sconn_addr;
temp = (uintptr_t)sconn->sconn_addr;
return ((uint32_t)(temp ^ (temp >> 16)));
}
#endif
@ -5704,7 +5722,7 @@ sctp_sorecvmsg(struct socket *so,
if (rwnd_req < SCTP_MIN_RWND)
rwnd_req = SCTP_MIN_RWND;
in_eeor_mode = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
if (SCTP_BASE_SYSCTL(sctp_logging_level) &SCTP_RECV_RWND_LOGGING_ENABLE) {
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_RECV_RWND_LOGGING_ENABLE) {
#if defined(__APPLE__)
#if defined(APPLE_LEOPARD)
sctp_misc_ints(SCTP_SORECV_ENTER,
@ -6459,8 +6477,8 @@ sctp_sorecvmsg(struct socket *so,
#else
if ((uio->uio_resid == 0) ||
#endif
((in_eeor_mode) && (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))
) {
((in_eeor_mode) &&
(copied_so_far >= (uint32_t)max(so->so_rcv.sb_lowat, 1)))) {
goto release;
}
/*
@ -6980,7 +6998,7 @@ sctp_hashinit_flags(int elements, struct malloc_type *type,
hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
else {
#ifdef INVARIANTS
SCTP_PRINTF("flag incorrect in hashinit_flags");
SCTP_PRINTF("flag incorrect in hashinit_flags.\n");
#endif
return (NULL);
}
@ -7004,7 +7022,7 @@ sctp_hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask)
hashtbl = vhashtbl;
for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
if (!LIST_EMPTY(hp)) {
SCTP_PRINTF("hashdestroy: hash not empty");
SCTP_PRINTF("hashdestroy: hash not empty.\n");
return;
}
FREE(hashtbl, type);
@ -7466,8 +7484,13 @@ sctp_bindx_delete_address(struct sctp_inpcb *inp,
int
sctp_local_addr_count(struct sctp_tcb *stcb)
{
int loopback_scope, ipv4_local_scope, local_scope, site_scope;
int ipv4_addr_legal, ipv6_addr_legal;
int loopback_scope;
#if defined(INET)
int ipv4_local_scope, ipv4_addr_legal;
#endif
#if defined (INET6)
int local_scope, site_scope, ipv6_addr_legal;
#endif
#if defined(__Userspace__)
int conn_addr_legal;
#endif
@ -7478,11 +7501,15 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
/* Turn on all the appropriate scopes */
loopback_scope = stcb->asoc.scope.loopback_scope;
#if defined(INET)
ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
#endif
#if defined(INET6)
local_scope = stcb->asoc.scope.local_scope;
site_scope = stcb->asoc.scope.site_scope;
ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
#endif
#if defined(__Userspace__)
conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
#endif

View File

@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 243186 2012-11-17 20:04:04Z tuexen $");
__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 257555 2013-11-02 20:12:19Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@ -178,7 +178,13 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
}
#endif
#if defined(__FreeBSD__)
#if __FreeBSD_version >= 800000
#if __FreeBSD_version > 1000049
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
"sctp6_input(): Packet of length %d received on %s with csum_flags 0x%b.\n",
m->m_pkthdr.len,
if_name(m->m_pkthdr.rcvif),
(int)m->m_pkthdr.csum_flags, CSUM_BITS);
#elif __FreeBSD_version >= 800000
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
"sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
m->m_pkthdr.len,
@ -457,8 +463,10 @@ sctp6_notify(struct sctp_inpcb *inp,
(icmph->icmp6_code == ICMP_UNREACH_ISOLATED) ||
(icmph->icmp6_code == ICMP_UNREACH_NET_PROHIB) ||
(icmph->icmp6_code == ICMP_UNREACH_HOST_PROHIB) ||
#ifdef __Panda__
#if defined(__Panda__)
(icmph->icmp6_code == ICMP_UNREACH_ADMIN)) {
#elif defined(__Userspace_os_NetBSD)
(icmph->icmp6_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
#else
(icmph->icmp6_code == ICMP_UNREACH_FILTER_PROHIB)) {
#endif
@ -1090,18 +1098,11 @@ sctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
}
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if (!MODULE_GLOBAL(ip6_v6only)) {
struct sockaddr_in sin;
struct sockaddr_in sin;
/* convert v4-mapped into v4 addr and send */
in6_sin6_2_sin(&sin, sin6);
return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin,
control, p));
} else {
/* mapped addresses aren't enabled */
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
/* convert v4-mapped into v4 addr and send */
in6_sin6_2_sin(&sin, sin6);
return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin, control, p));
}
#endif /* INET */
connected_type:
@ -1179,14 +1180,16 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
uint32_t vrf_id;
int error = 0;
struct sctp_inpcb *inp;
struct in6pcb *inp6;
struct sctp_tcb *stcb;
#ifdef INET
struct in6pcb *inp6;
struct sockaddr_in6 *sin6;
struct sockaddr_storage ss;
#endif
#ifdef INET
inp6 = (struct in6pcb *)so->so_pcb;
#endif
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
@ -1269,17 +1272,9 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
}
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
if (!MODULE_GLOBAL(ip6_v6only)) {
/* convert v4-mapped into v4 addr */
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
addr = (struct sockaddr *)&ss;
} else {
/* mapped addresses aren't enabled */
SCTP_INP_RUNLOCK(inp);
SCTP_ASOC_CREATE_UNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
return (EINVAL);
}
/* convert v4-mapped into v4 addr */
in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
addr = (struct sockaddr *)&ss;
}
#endif /* INET */
/* Now do we connect? */
@ -1690,7 +1685,7 @@ sctp6_getpeeraddr(struct socket *so, struct mbuf *nam)
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
struct pr_usrreqs sctp6_usrreqs = {
#if __FreeBSD_version >= 600000
#if defined(__FreeBSD__)
.pru_abort = sctp6_abort,
.pru_accept = sctp_accept,
.pru_attach = sctp6_attach,
@ -1714,46 +1709,52 @@ struct pr_usrreqs sctp6_usrreqs = {
.pru_sockaddr = sctp6_in6getaddr,
.pru_sosend = sctp_sosend,
.pru_soreceive = sctp_soreceive
#else
#elif defined(__APPLE__)
.pru_abort = sctp6_abort,
.pru_accept = sctp_accept,
.pru_attach = sctp6_attach,
.pru_bind = sctp6_bind,
.pru_connect = sctp6_connect,
.pru_connect2 = pru_connect2_notsupp,
.pru_control = in6_control,
.pru_detach = sctp6_detach,
.pru_disconnect = sctp6_disconnect,
.pru_listen = sctp_listen,
.pru_peeraddr = sctp6_getpeeraddr,
.pru_rcvd = NULL,
.pru_rcvoob = pru_rcvoob_notsupp,
.pru_send = sctp6_send,
.pru_sense = pru_sense_null,
.pru_shutdown = sctp_shutdown,
.pru_sockaddr = sctp6_in6getaddr,
.pru_sosend = sctp_sosend,
.pru_soreceive = sctp_soreceive,
.pru_sopoll = sopoll
#elif defined(__Windows__)
sctp6_abort,
sctp_accept,
sctp6_attach,
sctp6_bind,
sctp6_connect,
pru_connect2_notsupp,
#if defined(__Windows__)
NULL,
NULL,
#else
in6_control,
sctp6_detach,
#endif
sctp6_disconnect,
sctp_listen,
sctp6_getpeeraddr,
NULL,
pru_rcvoob_notsupp,
#if defined(__Windows__)
NULL,
#else
sctp6_send,
#endif
pru_sense_null,
sctp_shutdown,
#if defined(__Windows__)
sctp_flush,
#endif
sctp6_in6getaddr,
sctp_sosend,
sctp_soreceive,
#if !defined(__Windows__)
sopoll
#else
sopoll_generic,
NULL,
sctp6_close
#endif
#endif
};
#elif !defined(__Panda__) && !defined(__Userspace__)

View File

@ -55,14 +55,14 @@ int sctp6_input(struct mbuf **, int *);
int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
#elif defined(__Panda__)
int sctp6_input (pakhandle_type *);
#elif defined(__FreeBSD__) && __FreeBSD_version < 1000000
#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp6_input __P((struct mbuf **, int *, int));
int sctp6_input_with_port __P((struct mbuf **, int *, uint16_t));
#else
int sctp6_input(struct mbuf **, int *, int);
int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
#endif
#if defined(__FreeBSD__) && __FreeBSD_version < 1000000
#if defined(__FreeBSD__) && __FreeBSD_version < 902000
int sctp6_output
__P((struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct proc *));

View File

@ -33,11 +33,6 @@
#include <stdlib.h>
#if !defined (__Userspace_os_Windows)
#include <stdint.h>
#if !defined(__Userspace_os_FreeBSD)
#if !defined(ANDROID)
#include <sys/sysctl.h>
#endif
#endif
#include <netinet/sctp_os_userspace.h>
#endif
#include <user_environment.h>

View File

@ -35,13 +35,6 @@
#include <user_route.h> /* was <net/route.h> */
#if defined(ANDROID)
#include <arpa/inet.h>
#include <netinet/in.h>
/* missing defines in Android bionic libc/NDK */
typedef uint16_t in_port_t;
#endif
#define in6pcb inpcb /* for KAME src sync over BSD*'s */
#define in6p_sp inp_sp /* for KAME src sync over BSD*'s */
struct inpcbpolicy;
@ -56,7 +49,6 @@ struct inpcbpolicy;
*/
LIST_HEAD(inpcbhead, inpcb);
LIST_HEAD(inpcbporthead, inpcbport);
typedef u_quad_t inp_gen_t;
/*
* PCB with AF_INET6 null bind'ed laddr can receive AF_INET input packet.
@ -176,7 +168,6 @@ struct inpcb {
LIST_ENTRY(inpcb) inp_portlist;
struct inpcbport *inp_phd; /* head of this list */
#define inp_zero_size offsetof(struct inpcb, inp_gencnt)
inp_gen_t inp_gencnt; /* generation count of this instance */
struct mtx inp_mtx;
#define in6p_faddr inp_inc.inc6_faddr
@ -205,26 +196,6 @@ struct inpcb {
* don't concern ourselves with that possibility.
*/
/*
* Interface exported to userland by various protocols which use inpcbs. Hack
* alert -- only define if struct xsocket is in scope.
*/
#ifdef _SYS_SOCKETVAR_H_
struct xinpcb {
size_t xi_len; /* length of this structure */
struct inpcb xi_inp;
struct xsocket xi_socket;
u_quad_t xi_alignment_hack;
};
struct xinpgen {
size_t xig_len; /* length of this structure */
u_int xig_count; /* number of PCBs at this time */
inp_gen_t xig_gen; /* generation count at this time */
so_gen_t xig_sogen; /* socket generation count at this time */
};
#endif /* _SYS_SOCKETVAR_H_ */
struct inpcbport {
LIST_ENTRY(inpcbport) phd_hash;
struct inpcbhead phd_pcblist;
@ -271,7 +242,6 @@ struct inpcbinfo {
* Generation count--incremented each time a connection is allocated
* or freed.
*/
u_quad_t ipi_gencnt;
struct mtx ipi_mtx;
/*
@ -376,12 +346,7 @@ extern struct callout ipport_tick_callout;
void in_pcbpurgeif0(struct inpcbinfo *, struct ifnet *);
int in_pcballoc(struct socket *, struct inpcbinfo *);
int in_pcbbind(struct inpcb *, struct sockaddr *, struct ucred *);
int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
u_short *, struct ucred *);
int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);
int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,
u_short *, in_addr_t *, u_short *, struct inpcb **,
struct ucred *);
void in_pcbdetach(struct inpcb *);
void in_pcbdisconnect(struct inpcb *);
void in_pcbdrop(struct inpcb *);
@ -399,8 +364,6 @@ void in_pcbrehash(struct inpcb *);
void in_pcbsetsolabel(struct socket *so);
int in_getpeeraddr(struct socket *so, struct sockaddr **nam);
int in_getsockaddr(struct socket *so, struct sockaddr **nam);
struct sockaddr *
in_sockaddr(in_port_t port, struct in_addr *addr);
void in_pcbsosetlabel(struct socket *so);
void in_pcbremlists(struct inpcb *inp);
void ipport_tick(void *xtp);

View File

@ -95,7 +95,7 @@ struct ip6_hdr {
#endif
#endif
#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD)
#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD) && !defined(__Userspace_os_DragonFly)
struct route_in6 {
struct rtentry *ro_rt;
struct llentry *ro_lle;

View File

@ -163,9 +163,9 @@ struct mbstat {
* externally and attach it to the mbuf in a way similar to that of mbuf
* clusters.
*/
#define MLEN (MSIZE - sizeof(struct m_hdr)) /* normal data len */
#define MHLEN (MLEN - sizeof(struct pkthdr)) /* data len w/pkthdr */
#define MINCLSIZE (MHLEN + 1) /* smallest amount to put in cluster */
#define MLEN ((int)(MSIZE - sizeof(struct m_hdr))) /* normal data len */
#define MHLEN ((int)(MLEN - sizeof(struct pkthdr))) /* data len w/pkthdr */
#define MINCLSIZE ((int)(MHLEN + 1)) /* smallest amount to put in cluster */
#define M_MAXCOMPRESS (MHLEN / 2) /* max amount to copy for compression */
@ -267,7 +267,6 @@ struct mbuf {
#define M_PROTO3 0x0040 /* protocol-specific */
#define M_PROTO4 0x0080 /* protocol-specific */
#define M_PROTO5 0x0100 /* protocol-specific */
#define M_NOTIFICATION M_PROTO5/* SCTP notification */
#define M_SKIP_FIREWALL 0x4000 /* skip firewall processing */
#define M_FREELIST 0x8000 /* mbuf is on the free list */

View File

@ -35,7 +35,7 @@
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#if !defined(__Userspace_os_FreeBSD)
#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD)
#include <sys/uio.h>
#else
#include <user_ip6_var.h>
@ -56,7 +56,7 @@
#endif
#endif
#endif
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#include <net/route.h>
#endif
/* local macros and datatypes used to get IP addresses system independently */
@ -67,12 +67,12 @@
void recv_thread_destroy(void);
#define MAXLEN_MBUF_CHAIN 32 /* What should this value be? */
#define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#define NEXT_SA(ap) ap = (struct sockaddr *) \
((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (uint32_t)) : sizeof(uint32_t)))
#endif
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
static void
sctp_get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{
@ -183,7 +183,7 @@ recv_function_route(void *arg)
}
}
}
pthread_exit(NULL);
return (NULL);
}
#endif
@ -266,7 +266,7 @@ recv_function_route(void *arg)
}
}
}
pthread_exit(NULL);
return (NULL);
}
#endif
@ -360,6 +360,8 @@ recv_function_raw(void *arg)
}
#endif
SCTP_HEADER_LEN(recvmbuf[0]) = n; /* length of total packet */
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
SCTP_BUF_LEN(recvmbuf[0]) = n;
@ -404,44 +406,44 @@ recv_function_raw(void *arg)
/* SCTP does not allow broadcasts or multicasts */
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
return NULL;
return (NULL);
}
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, recvmbuf[0])) {
return NULL;
return (NULL);
}
port = 0;
#if !defined(SCTP_WITH_NO_CSUM)
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_recvnocrc);
#else
if (src.sin_addr.s_addr == dst.sin_addr.s_addr) {
compute_crc = 0;
SCTP_STAT_INCR(sctps_recvnocrc);
} else {
SCTP_STAT_INCR(sctps_recvswcrc);
}
#endif
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
SCTPDBG(SCTP_DEBUG_USR, " - calling sctp_common_input_processing with off=%d\n", offset);
sctp_common_input_processing(&recvmbuf[0], sizeof(struct ip), offset, n,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch,
#if !defined(SCTP_WITH_NO_CSUM)
compute_crc,
#else
0,
#endif
ecn,
SCTP_DEFAULT_VRFID, port);
if (recvmbuf[0]) {
m_freem(recvmbuf[0]);
}
}
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
m_free(recvmbuf[i]);
}
/* free the array itself */
free(recvmbuf);
#if defined (__Userspace_os_Windows)
ExitThread(0);
#else
pthread_exit(NULL);
#endif
return (NULL);
}
#endif
@ -553,6 +555,8 @@ recv_function_raw6(void *arg)
}
#endif
SCTP_HEADER_LEN(recvmbuf6[0]) = n; /* length of total packet */
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
SCTP_BUF_LEN(recvmbuf6[0]) = n;
@ -597,9 +601,14 @@ recv_function_raw6(void *arg)
src.sin6_len = sizeof(struct sockaddr_in6);
#endif
src.sin6_port = sh->src_port;
#if !defined(SCTP_WITH_NO_CSUM)
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_recvnocrc);
#else
if (memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0) {
compute_crc = 0;
SCTP_STAT_INCR(sctps_recvnocrc);
} else {
SCTP_STAT_INCR(sctps_recvswcrc);
}
#endif
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
@ -610,22 +619,18 @@ recv_function_raw6(void *arg)
sh, ch,
#if !defined(SCTP_WITH_NO_CSUM)
compute_crc,
#else
0,
#endif
0,
SCTP_DEFAULT_VRFID, 0);
if (recvmbuf6[0]) {
m_freem(recvmbuf6[0]);
}
}
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
m_free(recvmbuf6[i]);
}
/* free the array itself */
free(recvmbuf6);
#if defined (__Userspace_os_Windows)
ExitThread(0);
#else
pthread_exit(NULL);
#endif
return (NULL);
}
#endif
@ -740,6 +745,8 @@ recv_function_udp(void *arg)
n = ncounter;
#endif
SCTP_HEADER_LEN(udprecvmbuf[0]) = n; /* length of total packet */
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
SCTP_BUF_LEN(udprecvmbuf[0]) = n;
@ -789,10 +796,10 @@ recv_function_udp(void *arg)
/* SCTP does not allow broadcasts or multicasts */
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
return NULL;
return (NULL);
}
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, udprecvmbuf[0])) {
return NULL;
return (NULL);
}
/*offset = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);*/
@ -802,9 +809,14 @@ recv_function_udp(void *arg)
port = src.sin_port;
src.sin_port = sh->src_port;
dst.sin_port = sh->dest_port;
#if !defined(SCTP_WITH_NO_CSUM)
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_recvnocrc);
#else
if (src.sin_addr.s_addr == dst.sin_addr.s_addr) {
compute_crc = 0;
SCTP_STAT_INCR(sctps_recvnocrc);
} else {
SCTP_STAT_INCR(sctps_recvswcrc);
}
#endif
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
@ -815,22 +827,18 @@ recv_function_udp(void *arg)
sh, ch,
#if !defined(SCTP_WITH_NO_CSUM)
compute_crc,
#else
0,
#endif
0,
SCTP_DEFAULT_VRFID, port);
if (udprecvmbuf[0]) {
m_freem(udprecvmbuf[0]);
}
}
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
m_free(udprecvmbuf[i]);
}
/* free the array itself */
free(udprecvmbuf);
#if defined (__Userspace_os_Windows)
ExitThread(0);
#else
pthread_exit(NULL);
#endif
return (NULL);
}
#endif
@ -945,6 +953,8 @@ recv_function_udp6(void *arg)
n = ncounter;
#endif
SCTP_HEADER_LEN(udprecvmbuf6[0]) = n; /* length of total packet */
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
if (n <= iovlen) {
SCTP_BUF_LEN(udprecvmbuf6[0]) = n;
@ -980,7 +990,7 @@ recv_function_udp6(void *arg)
/* SCTP does not allow broadcasts or multicasts */
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
return NULL;
return (NULL);
}
sh = mtod(udprecvmbuf6[0], struct sctphdr *);
@ -990,9 +1000,14 @@ recv_function_udp6(void *arg)
port = src.sin6_port;
src.sin6_port = sh->src_port;
dst.sin6_port = sh->dest_port;
#if !defined(SCTP_WITH_NO_CSUM)
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_recvnocrc);
#else
if ((memcmp(&src.sin6_addr, &dst.sin6_addr, sizeof(struct in6_addr)) == 0)) {
compute_crc = 0;
SCTP_STAT_INCR(sctps_recvnocrc);
} else {
SCTP_STAT_INCR(sctps_recvswcrc);
}
#endif
SCTPDBG(SCTP_DEBUG_USR, "%s: Received %d bytes.", __func__, n);
@ -1006,18 +1021,15 @@ recv_function_udp6(void *arg)
#endif
0,
SCTP_DEFAULT_VRFID, port);
if (udprecvmbuf6[0]) {
m_freem(udprecvmbuf6[0]);
}
}
for (i = 0; i < MAXLEN_MBUF_CHAIN; i++) {
m_free(udprecvmbuf6[i]);
}
/* free the array itself */
free(udprecvmbuf6);
#if defined (__Userspace_os_Windows)
ExitThread(0);
#else
pthread_exit(NULL);
#endif
return (NULL);
}
#endif
@ -1074,7 +1086,7 @@ recv_thread_init(void)
#else
unsigned int timeout = SOCKET_TIMEOUT; /* Timeout in milliseconds */
#endif
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
if (SCTP_BASE_VAR(userspace_route) == -1) {
if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno);
@ -1375,7 +1387,7 @@ recv_thread_init(void)
}
#endif
#if !defined(__Userspace_os_Windows)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#if defined(INET) || defined(INET6)
if (SCTP_BASE_VAR(userspace_route) != -1) {
int rc;
@ -1467,7 +1479,7 @@ recv_thread_init(void)
void
recv_thread_destroy(void)
{
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
#if defined(INET) || defined(INET6)
if (SCTP_BASE_VAR(userspace_route) != -1) {
close(SCTP_BASE_VAR(userspace_route));
@ -1507,4 +1519,6 @@ recv_thread_destroy(void)
}
#endif
}
#else
int foo;
#endif

View File

@ -94,12 +94,7 @@ user_sctp_timer_iterate(void *arg)
}
SCTP_TIMERQ_UNLOCK();
}
#if defined (__Userspace_os_Windows)
ExitThread(0);
#else
pthread_exit(NULL);
#endif
return NULL;
return (NULL);
}
void

Some files were not shown because too many files have changed in this diff Show More